예제코드
정사각 영역에 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