Quick Reference
| 개념 | 의미 |
|---|---|
| Normal | 표면이 향하는 방향 |
| Tangent | UV의 U 방향에 대응하는 표면 방향 |
| Bitangent | UV의 V 방향에 대응하는 표면 방향 |
| TBN matrix | tangent space를 world/view space로 바꾸는 행렬 |
| Normal map | 표면 방향 변화를 텍스처로 저장 |
sampledNormal = normalMap.rgb * 2.0 - 1.0
shadingNormal = normalize(TBN * sampledNormal)
position uses model matrix; normal uses normal matrix when scale is non-uniform.구조
normal은 조명 계산에서 표면이 빛을 얼마나 향하는지 판단하는 핵심 벡터입니다. 기본 normal만 쓰면 저해상도 메시의 표면은 단순하게 보입니다. normal map은 텍스처에 방향 변화를 저장해 더 세밀한 표면처럼 보이게 합니다.
normal map의 RGB 값은 보통 tangent space 방향을 인코딩합니다. 이 벡터를 조명 계산에 쓰려면 TBN matrix를 통해 world 또는 view space로 변환해야 합니다.
normal map RGB
-> [-1, 1] vector
-> TBN transform
-> lighting normalTangent space
tangent space는 각 표면의 UV 기준 좌표계입니다. 같은 normal map을 여러 방향의 표면에 붙여도 표면 기준으로 올바르게 해석하려면 tangent, bitangent, normal이 필요합니다.
TBN은 orthonormal basis여야 합니다. vertex tangent와 normal을 보간한 뒤에는 다시 normalize하고, tangent에서 normal 성분을 제거해 직교화할 수 있습니다. bitangent를 vertex attribute로 모두 저장할지, tangent handedness 부호와 cross product로 복원할지는 asset format과 shader bandwidth의 선택입니다.
문제 추적
| 증상 | 의심할 원인 |
|---|---|
| 빛 방향이 이상하게 뒤집힘 | normal 방향, handedness |
| seam이 강하게 보임 | tangent basis 불일치 |
| 표면이 울퉁불퉁하지 않음 | normal map import, sRGB 설정 |
| 푸른 normal map이 이상한 색 | 데이터 텍스처를 색으로 처리 |
| 한쪽 면만 어두움 | backface, normal transform |
normal은 위치처럼 translation을 적용하면 안 됩니다. 비균일 scale이 있으면 inverse transpose normal matrix가 필요할 수 있습니다.
주의할 점
normal map은 색 텍스처가 아니라 방향 데이터입니다. sRGB decode나 색 보정이 들어가면 벡터 값이 깨질 수 있습니다.
또 tangent basis는 툴, 엔진, baker가 같은 규칙을 써야 합니다. MikkTSpace 같은 표준을 맞추지 않으면 seam이나 조명 불일치가 생길 수 있습니다.
normal map의 green channel 방향은 asset pipeline마다 뒤집혀 있을 수 있습니다. 한 축만 반대로 보이거나 light가 좌우로 뒤집히면 texture를 다시 색 보정하기 전에 normal map Y convention, tangent handedness, backface normal 처리 중 무엇이 다른지 확인합니다.
참고 링크
1 sources