메쉬 데칼맵

데칼을 구현은 투영 텍스쳐 데칼과 메쉬 데칼이 있다.
여기서는 메쉬 칼에 대해서 구현해 본다. GPG2권에도 있지만 웹검색을 해보니 Wolfire에서 메쉬 데칼에 대해서 친절하게 설명했다.

http://blog.wolfire.com/2009/06/how-to-project-decals/

Wolfire 메쉬 데칼 크라이 엔진 메쉬 데칼, 직접 Wolfire의 알고리즘에 따라 구현해본 메쉬 데칼을 그림으로 먼저 보자

[그림: Wolfire 메쉬 데칼]


[그림: 크라이 엔진 메쉬 데칼]

[그림: 직접 구현해본 메쉬 데칼]

Wolfire의 기본 알고리즘을 알아 보자.( 여기서 다이렉트X를 사용하지만 오른손 좌표계를 사용하고 있다.)

1. OBB 사각형은 직교 좌표계의 카메라로 생각해 월드 - 뷰 - 프로젝션 행렬을 이용해 버텍스를 변환한다.

2. 축 방향에 의해 클리핑한다.

3. 텍스쳐 좌표를 계산한다.

4. 이 외의 고려 사항

크게 3단계에 의해서 그려진다. 여기서는 생략 되었지만 데칼 맵으로 변환 해야 할 버텍스를 먼저 제외시켜야 데칼맵 변환시 속도를 빠르게 할 수 있다. 카메라의 방향에 따라 텍스쳐가 늘어날수 있다.
데칼맵 실행은  void DxClipPolygon::TestDecalmap()으로 실행한다.

1. 사각형은 직교 좌표계의 카메라로  월드 - 뷰 - 프로젝션 행렬을 이용해 버텍스를 변환한다.

D3DXMATRIXA16  mat = matWorld * matCameraView * matProj;
D3DXVec3TransformCoord(&out, &vec, &mat);

두 명령을 통해서 버텍스를 월드 - 뷰 - 프로젝션 행렬로 변환한다.
직교 행렬이므로 사각형으로 그리면  다음과 같다.

카메라는 월드-뷰-직교 투영 변환을 하면 x, y축은 -1, -1에서 1, 1사이, z축은 0에서 1로 변환된다.
가상의 카메라 사각형 밖의 버텍스는 클리핑 시킨다.

2. 축 방향에 의해 클리핑한다.

변환이 된 버텍스는 축방향으로 클리핑 시킨다. x, y 축 4축과 z축은 후면만 클리핑 시킨다.

    ClipAxis( 1, 0, 0, -1, false )
    ClipAxis( -1, 0, 0, 1, false )
    ClipAxis( 0, 1, 0, -1, false )
    ClipAxis( 0, -1, 0, 1, false )

    //z축 자르기
    ClipAxis( 0, 0, -1, 1, false )

3. 텍스쳐 좌표를 계산한다.'

월드-뷰-투영 행렬에 변환된 버텍스 좌표는 텍스쳐 좌표와 비슷 하여 텍스쳐 좌표로 변환하기 쉽다.

float u = 0.5f * vec.x + 0.5f
float v = -0.5f * vec.y + 0.5f
m_texUV.push_back( DataType::Point2( u, v ) )

4. 이외 고려사항

z-fighting이 일어 나지 않도록 데칼맵의 버텍스를 노멀값의 방향에 따라 조금 키워 준다.

m_pVertex[i].x = m_position[i].x + m_normal[i].x*0.01f
m_pVertex[i].y = m_position[i].y + m_normal[i].y*0.01f
m_pVertex[i].z = m_position[i].z + m_normal[i].z*0.01f

결론

메쉬 데칼맵의 구현은 카메라 사각형 박스안에 들어오는 버텍스를 빠른시간에 찾아내고, 사각형 박스의 방향을 적절하게 조절하여 텍스쳐가 늘어나지 않도록 해야 한다.