three.js의 TSL을 이용한 attribute 관련 코드

attribute를 위한 데이터인 Buffer Attribte를 생성하는 방식은 기존과 동일합니다.

const count = geometry.attributes.position.count
const randomArray = new Float32Array(count)

for (let i = 0; i < count; i++)
    randomArray[i] = Math.random()

const randomBuffer = new THREE.BufferAttribute(randomArray, 1)

// KEY POINT ->
geometry.setAttribute('random', randomBuffer)
const random = attribute('random')
// <-

material.colorNode = random

위의 코드는 다음 코드처럼 좀더 짧고 효과적으로 변경될 수 있습니다.

const count = geometry.attributes.position.count
const randomArray = new Float32Array(count)

for (let i = 0; i < count; i++)
    randomArray[i] = Math.random()

const randomBuffer = new THREE.BufferAttribute(randomArray, 1)

// KEY POINT ->
const random = bufferAttribute(randomBuffer, 'float')
// <-

material.colorNode = random

TypeScript, 읽기전용 튜플로부터 유니온 문자열 타입 얻기

대부분의 메타 프로그래밍에서처럼 TypeScript 역시 짧은 코드에 함축된 다양한 내재 기능이 적용되어 개발자에게 혼란스러움을 주는 경우가 많습니다. 아래의 코드가 그 예시인데요.

const methods = [
    "GET",
    "POST",
    "PUT",
    "DELETE"
] as const;

type Method = typeof methods[number];

위의 타입으로써 Method는 다음과 같습니다.

"GET" | "POST" | "PUT" | "DELETE"

여기에 적용된 TypeScript와 관련된 적용 기능 중 중요한 것을 2가지 뽑지면 as const를 통한 문자열 배열의 ‘읽기전용 튜플화’와 Indexed Access Type을 통한 ‘유니온 타입화’입니다.

three.js의 내장 Inspector의 console 탭 출력 API

const renderer = new THREE.WebGPURenderer({
    canvas: canvas,
    antialias: true,
    // forceWebGL: true 
});

renderer.inspector = new Inspector();

renderer.inspector.console.addMessage("info", "정보 메세지...");
renderer.inspector.console.addMessage("warn", "경고성 메세지...");
renderer.inspector.console.addMessage("error", "에러 메세지...");

렌더러의 forceWebGL을 활성화해도 작동합니다. addMessage의 첫번째 인자는 반드시 info, warn, error 문자열이 와야 하며 이외의 값이 지정되면 출력하지 않습니다. 상기 코드의 출력 결과는 다음과 같습니다.

쉐이더 코드 확인하기

const program = await renderer.debug.getShaderAsync(scene, camera, mesh)
console.log('**VERTEX SHADER CODE**\n\n', program.vertexShader)
console.log('**FRAGMENT SHADER CODE**\n\n', program.fragmentShader)

three.js, userData 노드

three.js는 Mesh 등과 같은 객체에 사용자 데이터를 넣기 위한 userData 속성이 있습니다. 이처럼 userData 속성에 저장된 값을 쉐이더에서 참조할 수 있도록 해주는 노드가 userData 노드입니다. 사용 예시는 다음과 같습니다.

mesh.userData.한글 = new THREE.Color('#ffff00')
material.outputNode = vec4(userData('한글'), 1)

이렇게 사용된 Mesh 객체를 통해 userData의 값이 변경되면 자동으로 TSL 코드를 통해 반영됩니다.