조명 효과는 vertex 마다 normal 과 비츼 방향을 내적해 구합니다. 범프 매핑에서는 픽셀마다 normal을 줘서 빛에 대한 효과를 줘서 표면에 울퉁불퉁하거나, 주름지고, 물결치는 것 같이 표면이 불균일하게 보이도록 합니다.
픽셀마다 normal을 얻어 오기 위해 텍스쳐 맵을 하나 더 사용합니다. 이 텍스쳐에 높이 값을 넣어서, 인접 픽셀간의 높이 차이를 통해 normal을 구할 수 있습니다.
[그림1]
위의 그림1은 높이 맵으로 만들어 놓은 것을 읽어서 법선 맵으로 만드는 소스의 부분입니다.
우선 텍스쳐를 높이 맵과 동일한 크기로 만들고, 텍스처에 읽은 후에 법선을 만들어 놓습니다. D3DXComputeNormalMap에서 뒤에 D3XCHANNEL_RED 부분은 높이 맵에서 ARGB에서 R 값을 읽어서 10을 scale로 높이를 만들어 비교후에 법선을 만든다는 뜻입니다. R * 10 이 해당 픽셀의 높이. 근처 픽셀의 높이 값을 구해 법선으 구한다.
월드 좌표계에 있는 빛과 픽셀에 있는 normal을 내적을 통해 계산을 하려면 같은 공간에 일치 시켜야 합니다. 2개의 공간에 있으니 둘 중에 하나를 변환시켜 같은 공간에 있으면 되는데, 월드 좌표계에 있는 빛을 픽셀이 위치한 좌표계로 옮기는게 좀 더 간단합니다. 픽셀이 위치한 좌표계는 여러 책을 보니 다양하게 정의를 하는데 vertex 공간 좌표계, tangent 공간 , 텍스쳐 공간 좌표계 라는 정의가 있습니다.
이 공간은 법선은 항상 양의 z축을 가리키는 좌표계입니다. tangent 공간이라고 정의하고 설명을 하겠습니다.
tangent 공간의 법선과 월드 공간 좌표계에 위치한 빛을 내적하려면, 위에 말했다시피 월드 공간 좌표계의 빛을 tangent 공간으로 변환을 해야 합니다. object space -> tangent space로 변환 하는 행렬을 찾도록 하겠습니다.
tangent 공간의 2가지 접선 벡터 T,B는 텍스쳐 맵에 정렬된 접선 벡터입니다.( 여기서 접선 벡터는 2개의 벡터가 붙어있다는 것에 중점을 두고 있습니다. 이 2개의 벡터를 외적하면 2개의 벡터와 직교하는 벡터가 만들어 집니다)
T는 텍스쳐 가로 좌표 u 에 따른 위치 변화 , B는 텍스쳐 세로 좌표 v에 따른 위치 변화로 구할 수 있습니다
밑에 그림에서 P, P1 ,P2 는 정점(vertex)의 위치를 나타냅니다. Q1,Q2는 이를 연결하는 벡터르 의미합니다.
밑에 위치한 식들은 T,B를 구하는 방법을 나타냅니다.
앞에 상수항은 후에 T,B 벡터들을 재 정규화 할때 normalize 가 되서 없어지기 때문에 생략 가능합니다.
참고 도서. Real-Time rendering - Tomas Eric 공저
DirectX 9 셰이더 프로그래밍 - 타카시 이마가레 저
3D 게임 프로그래밍 & 컴퓨터 그래픽을 위한 수학 - Eric Lengyel 저
Direct3D ShaderX - wolfgang F. engel 공저