개발 · 컴퓨터공학 / / 2024. 5. 4. 09:07

three.js에서 webgpu를 지원하나?

728x90
반응형

 

 

webgpu의 출시

나는 three.js를 재작년에 프로젝트로 처음 사용했었다. 한창 작년에 webgpu가 브라우저에서 정식 지원한다는 말을 들었을 때까지는 three.js가 webgl 기반 라이브러리라서, webgpu보다는 퍼포먼스의 한계가 있었던 걸로 기억한다. 

 

그러한 이유로 webgpu를 공부하기 시작했던 것인데, 이제 와서는 조금 찾아보니 three.js에서 webgpu를 지원한다는 이야기가 종종 들린다. 

 

만약 그렇다면 굳이 webgpu를 당장 하기보다는 three.js로 프로젝트를 만드는 편이 나을 수도 있겠다는 생각이 든다.

three.js에서 WebGPU를 지원하는가?

 

threejs는 최근 보편화가 되는 중이지만 WebGPU에 대해서는 한국에서 정보가 잘 없고,

three.js 커뮤니티에서도 지원은 하지만 버전별로 업데이트 현황이 달라서 실질적으로 사용하기는 쉽지 않다.

 

대신에 compute shader를 사용하는 GPGPU 방법을 사용하는지에 대해서 

희귀하게 한국인이 작성한 포스팅이 있어서 참고해본다.

 

GPUComputationRenderer

라는 것을 사용해서 gpu computing을 연산할 수 있는 것 같다. 해당 렌더러는 " three/examples/jsm/misc/GPUComputationRenderer.js " 경로에 있는 현재 threejs에서 공식으로 지원하는 모듈이다.

 

const gpuCompute = new GPUComputationRenderer(sizes.width, sizes.height, renderer)
const dtPosition = gpuCompute.createTexture();
const positionVariable = gpuCompute.addVariable('uCurrentPosition', simFragment, dtPosition )
gpuCompute.setVariableDependencies(positionVariable, [positionVariable])
gpuCompute.init()

GPUComputationRenderer를 이용해서 GPU에게 연산하라고 보내줄 texture를 생성하고 정의한다.

 

//simFragment
void main() {
    vec2 vUv = gl_FragCoord.xy / resolution.xy;
    vec2 position = texture2D( uCurrentPosition, vUv ).xy;
    gl_FragColor = vec4( position, 0.0, 1.0);
}

sim fragment는 fragment shader를 의미하는데 input output에 대한 변수는 각각 이미 명시되어있는 변수 gl_FragCoord, gl_FragColor를 사용하는 모양이다.

 

gpuCompute.setVariableDependencies(positionVariable, [positionVariable])

set variable dependencies는 GPU computing을 진행하는데 사용할 변수를 할당해준다. 자세한 것은 threejs docs를 참고해봐야할 것 같다.

 

const shaderMaterial = new Three.ShaderMaterial({
    uniforms: {
        color: { 
            value: new Three.Color(0x00ff00) // 1.0, 0.0, 0.0
        },
    },
    vertexShader: `
        void main() {
            gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position,1.0);
        }
    `,
    fragmentShader: `
        uniform vec3 color;
        void main() {
            gl_FragColor = vec4( color.xyz, 1.0 );
        }
    `
});

three.js에는 본래 지원하는 custom shader coding이 있다. vertex shader pixel(fragment) shader 모두 지원하는데

gpuCompute를 이용한 compute shader 작업은 GPUComputationRenderer가 필요한 것 같다.

 

const onUpdate = () =>
{

    controls.update()

    gpuCompute.compute() // gpu연산 실행

    material.uniforms.uTexture.value = gpuCompute.getCurrentRenderTarget(positionVariable).texture 
    
    // 데이터 텍스쳐에서 가져온 값들을 계속해서 버텍스 쉐이더에 uTexture 에전달

    renderer.render(scene, camera)

    window.requestAnimationFrame(onUpdate)
}

update를 하게되면 shader로 uniform texture를 전달하기 전에 gpu compute 작업을 먼저 진행하고 vertex shader로 전달한다.

즉 말그대로 compute shader처럼 동작한다고 생각하면 편할 것 같다.

 

결론

theejs에서 gpu computation이 가능하다

gpuCompute 라는 객체를 이용해서 compute shader multi threading작업을 threejs에서 진행할 수 있다. 

따라서 특히 compute shader 병렬처리 역할이 중요한 파티클과 같은 작업의 퍼포먼스를 threejs에서도 크게 향상시킬 수 있다. 이러한 과정을 잘 이용해보자.

 

threejs의 본래 기반인 webgl과 webgpu의 차이를 더 알고자 한다면 다음 링크를 참고해보자.

 

 

 

 

 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유