dFdx와 dFdy를 이용한 법선 벡터 계산

버텍스 쉐이더에서 정점을 흔들었을 경우 법선 벡터 역시 다시 계산을 해줘야 하는데, 이때 정점의 x와 y에 대한 편미분 값을 얻을 수 있는 dFdx와 dFdy를 이용하면 법선 벡터를 얻을 수 있습니다.

이런 경우 버텍스 쉐이더에 전달된 normal을 vary를 통해 프레그먼트 쉐이더로 전달할 필요가 없고 프레그먼트 쉐이더에서 법선 벡터를 계산해 주면 되는데, 프레그먼트 쉐이더에서 이에 대한 코드는 다음과 같습니다.

vec3 normal = normalize(
    cross(
        dFdx(vPosition.xyz),
        dFdy(vPosition.xyz)
    )
);

위의 vPosition은 버텍스 쉐이이더에서 재계산된 정점인데, 버텍스 쉐이더의 코드에서 보면 다음과 같습니다.

varying vec3 vPosition;

void main() {	
    vec3 posClone = position;
    posClone = /* 정점 흔들기(변경) */
    
    ...

    vPosition = modelMatrix * vec4(posClone, 1.0)).xyz;

    ...
}

적용 결과로 비교하면 먼저 dFdx와 dFdy를 통한 법선 벡터를 사용하지 않고 지오메트리를 통해 제공되는 법선 벡터를 그대로 사용한 경우는 아래와 같습니다.

버텍스 쉐이더에서 정점을 흔들어서 원래 제공된 법선 벡터가 맞지 않아 음영 효과가 제대로 표현되지 않는데, 이를 개선하기 위해 dFdx와 dFdy를 통한 법선 벡터를 사용한 결과는 다음과 같습니다.

보다 사실적인 3차원 시각화를 위한 후처리(Postprocessing)

웹에서 3차원 시각화에 대한 개발 문의가 있어 이와 연관된 모델을 시각화하는 예제를 간단히 만들어 보았고.. 아래의 영상은 그에 대한 결과입니다. 모델 데이터를 3차원으로 시각화하는 것은 상대적으로 복잡하지 않은데.. 이렇게 시각화된 장면을 보다 멋지게 표현되도록 다양한 효과를 적용할 필요가 있습니다. 아래의 화면은 먼저 모델을 시각화하고 몇가지 후처리를 통해 더욱 멋지게 보이도록 하였습니다.

아래는 다이아몬드에 대한 반짝거리는 효과를 중점적으로 적용한 영상입니다.

추가적으로 보석과 함께 금괴도 표현해본 영상입니다.

HDRI과 함께 3D 모델을 자연스럽게 시각화하기

HDRI는 조명으로써 매우 뛰어난 기능을 제공하면서 동시에 시각적인 배경으로도 사용될 수 있습니다. 그러나 HDRI가 배경으로 사용되면 3D 모델과 이질감이 느껴지는데 이런 이질감을 개선할 수 있습니다.

three.js에서 HDR 데이터를 이용한 배경 및 광원으로 사용하기

아래의 영상은 배경으로써의 HDRI를 모델과 함께 자연스럽게 표현하기 위해 작업한 코딩 결과입니다.

주변 환경을 비추는 객체 표현

환경맵(envmap)을 사용해서 주변 환경의 모습을 비추는 객체를 표현할 때 적용할 수 있는 코드입니다. 먼저 아무런 재질도 적용되지 않은 검정색 구체입니다.

위의 검정색 구에 주변 환경 이미지를 환경 맵 소스로 활용하는 코드는 다음과 같습니다.

const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 1024 );
this._mirrorSphereCamera = new THREE.CubeCamera( 0.05, 50, cubeRenderTarget );
this._scene.add( this._mirrorSphereCamera );
const mirrorSphereMaterial = new THREE.MeshBasicMaterial( { envMap: cubeRenderTarget.texture } );
this._sphere.material = mirrorSphereMaterial;

환경맵을 생성하는 CubeCamera 객체의 상태가 변경될 경우… 예를들어 카메라의 위치 등이 변경될 경우 다음처럼 update 매서드를 호출해줘야 합니다.

this._mirrorSphereCamera.update( this._renderer, this._scene );

이 글에 사용된 코드와 결과는 Three.js에서 제공되는 예제 코드 중 webgl_animation_skinning_ik.html에서 환경맵 적용에 대한 내용만을 정리한 것입니다.