kwan's note

노멀 매핑 - normal mapping 본문

graphics VR AR/Computer Graphics -Korea Univ

노멀 매핑 - normal mapping

kwan's note 2021. 6. 30. 11:45
반응형

본 학습노트는 2021년 1학기 고려대학교 한정현 교수님의 컴퓨터 그래픽스 강의를 수강하고 이 내용을 기반으로작성하였습니다.

 

이전노트:

https://reminder-by-kwan.tistory.com/141

 

이번 시간에는 물체의 표면을 표현하는 방식에 대해 알아보도록 하겠습니다.

실제 물체는 표면이 완전히 매끄러울 수 없기 때문에 아무리 매끄러운 표면에 울퉁불퉁한 이미지를 입혀봤자 실제와 같은 표현이 어렵습니다.

 

저는 건축공학을 공부했었는데 설계 수업에서 스케치업으로 모델링을하고 표면에 콘크리트 텍스쳐를 아무리 그럴듯하게 입혀도 랜더링 결과가 마음에 들지 않았습니다. 지금 생각해보면 실제 표면이 울퉁불퉁하지 않음에서 오는 한계가 아니었을까 합니다.

 

이제 본문으로 들어가자면 표면이 매끄러운 경우 아무리 벽돌 texture를 입혀도 빛이 매끈한 면에 대해 반사되므로 사실적인 표현이 어려워 집니다.

 

아래는 고해상도 메시와 매끈한 매시의 비교입니다.

 

하지만 이런 고해상도 메시로 바닥을 표현하는것은 매우 비효율적입니다. 울퉁불퉁한 바닥을 만드는것이 매우 귀찮고 복잡한 작업이기 때문입니다. 또한 이런 메시를 처리하는데 너무나 많은 시간이 필요하게 됩니다.

 

이제 이러한 고해상도 매시 표면을 근사하면서 높은 품질을 얻는 방법에 대해 고민해 보겠습니다.

 

먼저 고해상도 메시와 아닌것의 차이가 어디서 오는지 생각해 봅시다.

가장 큰 이유는 이런 고해상도 메시는 normal이 다 다른 반면 매끈만 표면은 normal이 모두 평행하다는것에 있습니다.

따라서 면은 그대로 유지하면서도 normal을 변형한다면 높은 퀄리티의 표면을 얻을 수 있을 것 입니다.

 

따라서 한가지 해결 방법은 고해상도 메시의 노멀만 미리 저장해 놓은 후 이 노멀맵을  저해상도 메시의 normal 값을 바꿔치기 하면 됩니다.

 

하지만 모든 표면에 대해 고해상도 mesh를 이용하여 직접 normal을 구하는것은 어렵습니다. 따라서 이런 고해상도 메시가 없는경우 height map을 이용하여 normal map을 구하고자 합니다.

height map을 구하는 방식은 mesh에서 높이만을 따로 떼오는것이다. 즉 정해진 퀀텀마다 높이를 추출해와서 height map을 만든다. 만들어진 height map을 회색조로 표현하면 오른쪽 그림과 같이 된다.(0~255로 normalize)

 

이렇게 만든 height map을 이용하면 연산량이 고해상도 mesh를 직접 이용하는것보다 훨씬 적어진다.

이제 height map을 이용해 어떻게 normal map을 만드는지 보자

각각의 height 값에 대해 주변(x y 에 대해 각각 +1, -1)하여 직선을 긋는다. 그어진 두개의 선분을 이용해 해당 점에서의 normal을 구하게 된다.

 

이제 이렇게 얻어진 normal map을 이용하려면 polygon mesh가 rasterize 된후 texture의 좌표를 통해 normal map에서 normal 값을 읽어올 수 있게된다. 이를통해 phong model과 같은 lighting model에서 연산에 사용된다.

 

매우 적은 연산으로도 실제와 같은 효과를 낼 수 있기때문에 실제 3차원게임의 대부분에서 이러한 방식을 사용해 처리한다.

 

지금까지 만들어낸 normal map을 바닥면등에 mapping했다. 하지만 normal map이 항상 평평한 표면에 적용되는것은 아니다. 만약 구와 같은 도형에 normal map을 이용해 texturing을 한다면 해당 점에서의 normal은 tangent 평면의 normal을 shake한 형태가 될 것이다. 즉 그냥 normal map의 데이터를 그대로 사용하면 이상한 값을 갖게된다(평면이 아니므로). 따라서 표면의 접선에 맞는 normal을 사용해야 한다. 이제 이 tangent space에 대해 생각해 보도록 하겠다.

즉, 3차원 물체에서 normal map을 어떻게 사용해야하는지 살펴보자.

p점을 기준으로 tangent plane에 수직인 직선을 Np라고 하고 평면에 포함되며 Np에 수직인 두 벡터를 Tp, Bp라고 하자.

이러한 벡터들은 모든 점에 대해 새로이 갖게 된다.

이 점을 랜더링 하는경우 normal은 Np를 이용할 것이다. 하지만 normal mapping하는경우는 Np가 아닌 normal map에서 p에 해당하는 점의 normal인 n(sp,tp)값을 가지게 된다.

 

즉, n(sp,tp) 가 Np를 대체할 것이다. 이런 n(sp,tp)은 p의 tangent space에서 정의된 좌표이다. 즉 object space에서 n(sp,tp)를 직접사용하면 안된다. 지금까지 그냥 normal map이라고 했던 normal의 집합을 실제로는 tangent-space normal map이라고 부른다. 따라서 tangent space로부터 obj space 까지 변환을 시켜주면 obj space에서 normal을알 수 있다. 또는 light vector를 tangent 공간으로 이전시켜 계산해도 동일한 결과를 얻을 수 있다.

반응형