본문 바로가기
Shader

유니티 엔진의 노말맵은 노랑색? 흑백? 파랑색? : Unity Normal Map Color

by 대마왕J 2016. 5. 29.

이번에 오버워치에 관련한 문서때문에 노말맵이 왜 노랑이냐는 질문이 들어와서 ... 

그걸 간단하게 말할 수도 있지만 사실 제대로 말하려면 노말맵의 기본부터 얘기해야 하는 항목이라서 말이죠 


그래서 한번 간단하게 써 보겠습니다. 

복잡하게 쓰자니 굉장히 길어질 것 같아서요 ㅎㅎㅎ


일단 노말맵의 기본에 대해 알아보겠습니다. 


우리가 아는 노말맵은 이런 모습입니다. 파랑이라고 하죠. 


뭐 .. 틀린건 아닙니다만 솔직히 저게 파랑이라고요? 저게? 

솔직히 파랑이라고 보기엔 좀 애매한 색 아닙니까? 


노말맵이 왜 파랑인지는 아마 제 수업 들은 분들은 다 알테니까 패스하거나 다음 기회에 쓴다 하고 

뭐 일단 저게 일반적으로 우리가 아는 노말맵의 파랑 맞습니다. 

R 은 X를 G는 Y를 B는 Z 를 나타내는거죠 


근데 저거.. 그냥 저렇게 쓸 수가 없습니다. 

당장 각 채널의 색상은 0~1 범위로 되어 있고, 이를 그냥 각도로 변환하면 90도밖에 안된다고요. 노말맵은 각도마다 180도를 나타내야 하는데....


그래서 UnpackNormal 함수 안을 보면 *2-1 이 들어 있습니다. 0~1 을 -1 ~ 1 로 변환하는거지요 

그래서 진짜 쓰이는 노말맵은 사실 다음과 같은 모양입니다.  

이건 어떤 엔진이나 마찬가지예요. 





뭐 좋은데.. 






근데 여기서 또 한 가지 문제가 있습니다. 0~1을 -1 ~ 1 로 확장시켜 쓰는건 좋은데... 문제는 텍스쳐의 대역폭입니다. 

게임에서 쓰이는 텍스쳐는 무압축 파일을 쓴다면 또 모르겠는데, 일단 게임 텍스쳐는 보통 압축을 씁니다 . 

그러다보니 기본적으로 5:6:5 DXT 압축이 되어 있는 상태라 X와 Y의 대역폭이 32와 64밖에 안되는데다가 , 거기에 한번 더 압축하면서 디테일도 깨져버립니다. 이건 심각하죠 


그래서 퀄리티를 제대로 살리기 위한 꼼수를 쓰게 됩니다. 


일반적인 파일 포맷을 안쓰는 겁니다! 


유니티는 일단 노말맵일 경우 일반 Texture 타입이 아닌 Normalmap 타입으로 만들어야 하는건 알고 계실겁니다. 

나중에 UnpackNormal로 다시 변환 시켜주지요. ...언팩 노말..? 즉 노말은 패킹되어 있다..? 호오.. .




네 맞습니다. 노말맵은 패킹되어 있습니다. 특수한 포맷으로 말이죠/



보시면 알겠지만 DXTnm 포맷입니다. 


이 포맷은 사실 RGB로 존재하는 포맷이 아닙니다! 특이하게도 X와 Y를 a 와 g 포맷으로 변환합니다. 

즉 X와 Y만 있는 포맷이란거죠. 


이 부분에 대해서는 다음 링크를 확인하면 좋습니다 .

http://tech-artists.org/wiki/Normal_map_compression


DXT5nm

DXT5nm is the same file format as DXT5 except before compression the red channel is moved into the alpha channel, the green channel is left as-is, and the red and blue channels are blanked with the same solid color. This re-arranging of the color channels is often called swizzling.

The Green and Alpha channels are used because in the DXT format they are compressed using somewhat higher bit depths than the Red and Blue channels. Red and Blue have to be filled with the same solid color because most DXT compressors use an algorithm that compares differences between the three color channels. If you try to store some kind of texture in Red and/or Blue (specular power, height map, etc.) then the compressor will create more compression artifacts because it has to compare all three channels.

There are some options in the NVIDIA DXT compressor that help reduce the artifacts if you want to add texture to the Red or Blue channels. The artifacts will be greater than if you keep Red and Blue empty, but it might be a trade-off worth making. Some notes in this thread on the NVIDIA Developer Forums.




(*모바일에서는 이렇게 쓰지 않고 일반 텍스쳐로 씁니다)


뭐 하여간 그래서 이 노말맵은 사실 RGB로 되어 있지 않으므로 이걸 그냥 텍스쳐 출력하면 흑백으로 출력되더군요 사실은 RG 인데.. 





그럼 하여간 RG만 있는 파일로 어떻게 노말맵을 만드느냐?!?!? 


거기서부터는 수학을 끼얹으면 됩니다. 



inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal)

{

fixed3 normal;

normal.xy = packednormal.wy * 2 - 1;

normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));

return normal;

}


이렇게 cginc에 정의되어 있는걸 보시면 아시겠죠 


wy란 ag를 뜻하는 말이므로, 이걸 확장해줘서 normal.xy를 만들고, 

z 는 


normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy))); 로 추출해 내고 있습니다. 


이렇게 추출해 내면 z 값이 없어도 충분히 구현 가능합니다. 


그렇다보니까 노말맵에서 z값. 즉 파랑 채널은 사용하지 않아도 되므로 , 노랑색으로 노말맵을 만들어도 충분하다는 것입니다. 


반응형

'Shader ' 카테고리의 다른 글

Volumetric Rendering: Surface Shading  (0) 2016.07.28
굴절 셰이더 만들기 / Unity Refraction Shader  (9) 2016.07.26
카메라 방향에 상관없는 Matcap 만들기  (0) 2016.03.26
Shader Test  (0) 2016.03.26
저렴한 오버레이 공식  (0) 2016.02.20

댓글