R3F: Instances

Geometry instances 기법을 사용하여 성능을 향상시키는 방법을 소개합니다.

2025-08-16

예제코드

Instances

정사각 영역에 Box 인스턴스 배치

먼저 <instancedMesh>, <boxGeometry>, meshLambertMaterial 를 사용하여 정사각 영역에 Box 인스턴스를 배치합니다.

const id = i++;
o.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI);
o.position.set(halfRoot - x + Math.random(), halfRoot - y + Math.random(), halfRoot - z + Math.random());
o.updateMatrix();
ref.current.setMatrixAt(id, o.matrix);

렌덤값을 추가하여 rotation, position 값을 설정합니다. updateMatrix() 메서드를 호출하여 인스턴스의 행렬을 업데이트하고, setMatrixAt(id, o.matrix)를 사용하여 해당 인스턴스의 행렬을 설정합니다.

색상의 적용

schemeCategory10 색상을 렌더링하려는 사각형 개수 만큼 랜덤하게 배치합니다.

const colors = React.useMemo(
  () =>
    new Float32Array(
      Array.from({ length: count }, () => c.set(schemeCategory10[Math.floor(Math.random() * 10)]).toArray()).flat()
    ),
  [count]
);

각 인스턴스에 적용할 색상 버퍼를 <instancedBufferAttribute> 컴포넌트에 attributes-color attach prop으로 전달합니다.

<instancedBufferAttribute attach="attributes-color" args={[colors, 3]} />

커스텀 세이더를 사용하여 윤곽선 표시

또 다른 <instancedMesh>를 사용하여 윤곽선을 표시합니다. 이미 만들어진 인스턴스의 geometry와 instanceMatrix를 재사용하여 동일한 구성을 합니다.

outlines.current.geometry = ref.current.geometry;
outlines.current.instanceMatrix = ref.current.instanceMatrix;

fragment shader가 동작하는 위치의 중심으로부터의 거리를 계산하여 edge를 표시하는 세이터를 적용합니다.

  void main() {
    vec3 d = abs(vPosition) - (size * 0.5);
    float a = smoothstep(thickness, thickness + smoothness, min(min(length(d.xy), length(d.yz)), length(d.xz)));
    gl_FragColor = vec4(color, 1.0 - a);
  }`

polygonOffset을 사용하면 겹치는 폴리곤 중 한쪽에 약간의 오프셋(깊이 편차)을 주어 한 폴리곤이 다른 폴리곤 위에 정상적으로 보이게 할 수 있습니다

참조: offset

Loading script...