셰이더와 GPU 파이프라인 · 노멀과 접선 공간 · 실습
평면을 울퉁불퉁하게 보이게
목표
법선을 텍스처에 담고, 그것으로 평평한 면을 울퉁불퉁하게 보이게 만듭니다. 이 실습이 끝나면 노멀 맵이 왜 그 연보라빛인지, 접선 공간이 왜 필요한지 설명할 수 있게 됩니다.
왜 중요한가
사람이 요철을 알아보는 단서는 대부분 밝기의 변화입니다. 밝기는 법선과 빛 방향의 내적으로 정해지므로, 기하를 바꾸는 대신 법선만 픽셀마다 바꿔치기하면 같은 효과가 납니다. 삼각형 두 개짜리 평면에 벽돌의 요철이 생깁니다.
여기서 중요한 것이 어느 좌표계의 법선을 담느냐 입니다. 월드 공간 법선을 담으면 물체가 회전하는 순간 전부 틀립니다. 그래서 표면을 기준으로 한 좌표계(접선 공간)에 담고, 그 좌표계에서 "평평함" 은 언제나 (0, 0, 1) 입니다. 노멀 맵이 전체적으로 연보라로 보이는 것이 그 값의 색입니다.
단계
1. /root/normalmap 에 도구 상자를 놓습니다.
2. /root/normalmap/encode.py — 법선과 색 사이의 변환.
3. /root/normalmap/out/normalmap.png — 반구 격자 노멀 맵.
4. /root/normalmap/tbn.py — 접선 공간의 세 축.
5. /root/normalmap/out/flat.png — 상수 법선으로 비춘 평면.
6. /root/normalmap/out/bumped.png — 노멀 맵으로 비춘 같은 평면.
7. /root/normalmap/out/l0.png ~ l5.png 와 out/07-sweep.txt — 빛을 옮기며.
참고
- 그림은
nohup python3 -m http.server 8080 -d /root/normalmap/out &로 띄우고 웹 미리보기 에서http://localhost:8080/을 엽니다. 여섯 장이 돌아가면 요철이 빛을 따라 반응하는 것이 보입니다. - 이 실습의 평면은 XY 평면에 표준 UV 라 접선 공간이 월드 공간과 같습니다. 그래서 TBN 변환이 항등이 되어 계산이 단순해집니다. 다른 자세의 물체였다면 반드시 거쳐야 합니다.
- 흔한 실수 하나:
decode에서 정규화를 빠뜨리는 것입니다. 8비트로 잘리면서 길이가 1 이 아니게 되어 밝기가 미세하게 틀어집니다. - 흔한 실수 둘: 색을 정수로 자를 때 255 를 넘기는 것입니다. 밝은 곳이 이상한 색으로 뒤집힙니다.
단계 7개
- 그리기 도구 상자를 놓는다
- 법선을 색으로
- 노멀 맵을 만든다
- 접선 공간의 세 축
- 상수 법선으로 비춘다
- 노멀 맵으로 비춘다
- 빛을 움직인다