매트캡

Matcap

조명 계산 없이, 구를 미리 찍어둔 텍스처 하나로 재질의 명암·반사를 흉내 내는 기법.

다른 이름: Material captureMeshMatcapMaterialSpherical reflection map
···
js
import * as THREE from 'three';
function makeMatcap() {
  const size = 256;
  const c = document.createElement('canvas');
  c.width = size; c.height = size;
  const ctx = c.getContext('2d');
  ctx.fillStyle = '#14141f';
  ctx.fillRect(0, 0, size, size);
  const cx = size / 2, cy = size / 2, r = size / 2;
  const base = ctx.createRadialGradient(cx - r * 0.3, cy - r * 0.35, r * 0.05, cx, cy, r);
  base.addColorStop(0, '#dfe7ff');
  base.addColorStop(0.35, '#7f8fe0');
  base.addColorStop(0.7, '#3a3f8a');
  base.addColorStop(1, '#0d0d20');
  ctx.fillStyle = base;
  ctx.fillRect(0, 0, size, size);
  const spec = ctx.createRadialGradient(cx - r * 0.32, cy - r * 0.38, 0, cx - r * 0.32, cy - r * 0.38, r * 0.22);
  spec.addColorStop(0, 'rgba(255,255,255,0.95)');
  spec.addColorStop(1, 'rgba(255,255,255,0)');
  ctx.fillStyle = spec;
  ctx.fillRect(0, 0, size, size);
  return c;
}
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0b0b14);
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
camera.position.set(0, 0, 5);
const matcapTex = new THREE.CanvasTexture(makeMatcap());
matcapTex.colorSpace = THREE.SRGBColorSpace;
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1.4, 64, 64), new THREE.MeshMatcapMaterial({ matcap: matcapTex }));
scene.add(mesh);
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
renderer.setAnimationLoop((t) => {
  mesh.rotation.y = t * 0.0004;
  mesh.rotation.x = Math.sin(t * 0.0002) * 0.3;
  renderer.render(scene, camera);
});

매트캡(material capture) 텍스처는 조명 아래 놓인 구를 정면에서 찍은 사진 한 장입니다. 렌더링할 때는 화면 공간으로 변환한 표면 법선(normal)의 x, y 값을 그대로 그 텍스처의 UV 좌표로 써서 색을 읽어옵니다 — 즉 "이 방향을 보고 있는 면은 저장된 구 사진에서 이 위치의 색"이라는 룩업 한 번이 전부입니다.

그래서 MeshMatcapMaterial은 씬에 라이트를 하나도 안 둬도 금속·점토·유리 같은 질감을 즉시 보여주고, 연산 비용도 매우 낮습니다. 이 데모는 이미지 파일 대신 canvas 2D API로 방사형 그라데이션 몇 겹을 그려 매트캡 텍스처를 직접 만들고 CanvasTexture로 넘깁니다.

단점은 조명이 텍스처에 "구워져" 있어서 카메라가 움직여도 광원이 절대 움직이지 않는다는 것 — 그림자도 없고 실제 조명 방향과도 무관합니다. 빠른 프리뷰나 스타일화된 룩에는 좋지만 사실적인 라이팅이 필요하면 PBR 머티리얼을 쓰세요.

언제 쓰나

빠른 프로토타입, 조각/클레이 느낌의 스타일화된 룩, 라이트를 두기 어려운 초경량 씬에.