Graphics Programming

법선 매핑(normal mapping) 본문

Season 1/OpenGL

법선 매핑(normal mapping)

minseoklee 2016. 1. 26. 00:22

http://codeonwort.tistory.com/235


평면 텍스처에 입체감을 주기 위해 가장 흔하게 사용하는 기법이며 튜토리얼도 수없이 많으나... 구현하는 것은 엄청 힘들었다. 셰이딩을 위해서는 법선, 탄젠트, 바이탄젠트, 광원 위치, 시선 벡터, 모델뷰 행렬 등 많은 매개변수가 필요한데, 각자 다른 좌표계에서 정의된 값들이고 이것들을 모두 탄젠트 공간으로 변환해서 계산하는 과정에서 엄청난 혼란을 겪었기 때문이다. 그렇다고 수많은 픽셀 중 하나의 값을 찍어볼 수도 없어서, C++ 코드로 똑같은 계산을 작성해서 콘솔에 찍어보며 디버깅을 했다. 철저히 검증했는데도 GPU와 CPU에서의 결과가 다르다면, 매개변수를 전달하는 과정에서 오류가 난 것이다. 실제로 프래그먼트 셰이더의 mat4 유니폼에 glUniformMatrix3fv()로 4x4 행렬을 전달하는 코드를 작성했는데, 당연히 값은 잘못 설정되면서도 오류는 발생하지 않아서 원인을 찾느라 고생했다.



검색해보면서 법선 매핑을 한 것과 안 한 것의 차이는 많이 봤지만, 직접 구현한 결과를 보는 것은 놀랍다.



원본 텍스처

(http://opengameart.org/content/50-free-textures-4-normalmaps)


법선 매핑은 표면의 울퉁불퉁함이 크지 않을 때 쓰는 단순한 방법이다. 벽돌 텍스처에서 실제로 위의 벽돌이 아래의 벽돌을 가리는 식의 렌더링은 불가능하다. 변위 매핑은 그것이 가능한데, 오래 전에 관련 글을 번역했지만(http://codeonwort.tistory.com/235) 아직 구현에는 손도 못 대었다. 다음 목표는 이것이 될 것 같다. 요즘 한창 OpenGL 코딩을 하면서 느끼는 것은 머리로 아는 것과 실제로 구현하는 것은 다르다는 것이다. 뻔한 이야기지만, OpenGL의 경우는 특히 그러한 것이 API를 잘못 사용해서 버그가 일어나고 그것을 잡는 데 상당한 시간을 소모하기 때문이다. 이게 그냥 내가 못난 건지, 잘 정돈된 객체지향 세계의 API만 써서 C 스타일의 라이브러리를 제대로 못 익히는 건지...


Comments