개발 · 컴퓨터공학 / / 2024. 9. 30. 18:57

three.js GPGPU - GPUComputationRenderer 사용하기

728x90
반응형

 

https://medium.com/@p5js/threejs-%EC%97%90%EC%84%9C-gpgpu-%EC%82%AC%EC%9A%A9-01-be4090b8e3a4

 

Threejs 에서 GPGPU 사용 01

많이들 사용하지만 한글로된 자료가 부족해서 적어보는..

medium.com

이 포스팅을 이어서 작업해보자. 

 

vertex shader point size

glsl로 material을 바꾸니 point가 안보인다.

점이 너무 작아서 그런가.

 

//vertexshader
void main()
{
    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
    gl_PointSize = 10.0 / -mvPosition.z;
    gl_Position = projectionMatrix * mvPosition;
}

vertex shader에 point size를 추가한다. 

 

이제 잘 보인다. 

 

GPUComputationRenderer

const gpuCompute = new GPUComputationRenderer(canvas.clientWidth,  canvas.clientHeight, renderer)
const dtPosition = gpuCompute.createTexture();
const positionVariable = gpuCompute.addVariable('uCurrentPosition', simFragment, dtPosition )
gpuCompute.setVariableDependencies(positionVariable, [positionVariable])
gpuCompute.init()

이렇게 gpu computation renderer 설정 코드를 첨가하는데.

simulation fragment 라는 shader를 추가해보자.

 

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

 

 

GPU computation renderer로 texture를 생성한 후, 

이 텍스처를 이용해서 texel 한 칸 한 칸에서 compute shader의 역할을 수행할 것이다.

 

const positionVariable = gpuCompute.addVariable('uCurrentPosition', simFragment, dtPosition )

현재는 텍스처에 position정보를 담아서 사용할 것이다. 

 

gpuCompute.setVariableDependencies(positionVariable, [positionVariable])

그 다음 이전의 variable 상태에 기반해서 다음이 계산되도록 의존성을 세팅한다. 

 

gpuCompute.init()

초기화를 해준다.

 

GPUComputationRenderer 사용하기

const material = new THREE.ShaderMaterial(
    {
        uniforms: {
            uTexture:{ value: null },
        },
        vertexShader: vertexShader,
        fragmentShader: fragmentShader
    }
)

material에 uniform 변수 추가

 

function animate() {
  requestAnimationFrame(animate);

  if (resizeRendererToDisplaySize(renderer)) {
    const canvas = renderer.domElement
    camera.aspect = canvas.clientWidth / canvas.clientHeight
    camera.updateProjectionMatrix()
  }

  gpuCompute.compute();
  material.uniforms.uTexture.value = gpuCompute.getCurrentRenderTarget(positionVariable).texture;

  renderer.render(scene, camera);
}

애니메이션에서 gpu 연산 후 텍스처를 반영하기.

 

//simFragment
void main() {
    vec2 vUv = gl_FragCoord.xy / resolution.xy;
    vec2 position = texture2D( uCurrentPosition, vUv ).xy;

    position.x += 0.001;
    
    gl_FragColor = vec4( position, 0.0, 1.0);
}

simulation fragment shader를 texture로 받은 uCurrentPosition으로 position을 만들고,

position 값을 변경해서

vertex shader에서 변경된 새로운 position을 반영하는 방식이다.

 

uniform sampler2D uTexture;

//vertexshader
void main()
{
    vec3 newpos = position;
    vec4 color = texture2D(uTexture, uv);

    newpos.x += color.x;

    vec4 mvPosition = modelViewMatrix * vec4(newpos, 1.0);
    gl_PointSize = 10.0 / -mvPosition.z;
    gl_Position = projectionMatrix * mvPosition;
}

new position을 gl_Position에 반영하면 

 

조금씩 이동한다.

 

이제 이 GPU사용 방법으로 SPH에 반영할 수 있게 해보자.

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