노멀맵
노멀맵
- 노멀은 버택스간 노멀 보간에서 얼마나 차이가 있는지, 즉 면에 대해
상대적으로 노멀이 다른것을 백터로 표시한 맵이다.
- 노멀맵을 사용하지 않으면 스펙큘러 라이트가 맺힐때 분명하게 음영 차이남.
- 왜 노멀맵은 푸른색 일까? 노멀맵은 시각정보가 아닌 데이터이며,
벡터는 -1~1이지만 텍스처는 0~1 사이로 리맵하여 만들어 저장할수 한다.
z값은 저장하지 않고 x,y로 계산하여 사용하여 값을 만들어내며
다른 값에는 고정값을 그냥 넣는것으로 보인다.
- DXTnm 파란색이 아니라 보라색인 이유? #8888FF 이 유니티에서 보는
노말맵 보라색인데 x,y의 -1~1 -> (m+1)/2로 0 ~ 1로 리맵하기 떄문에
0값이 중간값인 0.5가 되는것이다. x,y로 z는 계산하므로 의미없는 값으로 1
- ASTC의 경우 좀 더 파란색으로 보이는데 이유는 잘 모르겠지만 리맵에 차이가 있는듯.
- 쉐이더 그래프에서는 연보라보다 제대로된 파란색으로 보이며 -1~1 사이로
노멀 텍스처를 역리맵한 결과를 보여준다. 쉐이더에서 노말맵을
SampleTexture 2D에 넣어 Default로 지정시 빨강으로 보이는데 Normal Unpack을 거치면 실제 Normal로 보인다.
- 보통 노말맵 타입으로 텍스처 지정하는 이유는 기존 텍스처가 감마 콜렉션으로
변형이 일어나면 안되야 하기 때문에 노멀맵 타입으로 설정하면 컬러스페이스
보정이 일어나지 않는다. 또한 지정시 노멀맵 데이터형식이 아닌 텍스처는 노멀
맵으로 만들어준다.
- 노멀맵은 특별한 방법으로 압축 저장한다. 노멀이 길이가 1이므로 텍스처
압축시 x,y만 저장하여 정밀도를 아끼고 대신 퀄리티를 높여 저장하며 Z는
쉐이더에서 연산하여 값을 계산한다.
- DXTnm, ASTC UNorm 이렇게 별도의 데이터 포맷을 제공하며 다른 포맷은
지원하지 않는곳도 있다. 서로 압축시 오염을 안시키기 위해 아래 그림처럼
떨어뜨려 저장. 실제로 아래 그림에서 보이는 텍스처는 x,y를 제자리로 놓은뒤
나오는 텍스처의 이미지라고 볼 수 있으며 압축을 풀어 표현한것이다.
![](https://velog.velcdn.com/images/kimpro/post/9ca0f3c9-c42f-4241-8879-c893f16e7450/image.png)
- DXT5 포맷은 채널압축이 R/5bit, G/6bit, B/5bit, A/8bit 으로
상대적으로 bit 크기가 큰 G, A를 사용한다. 노말맵을 더 섬세하게 표현가능.
- UnpackNormal 함수는 단순 리맵이며, PC의 경우 else에서 DXT5nm의
w(x),y(y)를 사용한다.
inline fixed3 UnpackNormal(fixed4 packednormal)
{
#if defined(SHADER_API_GLES) defined(SHADER_API_MOBILE)
return packednormal.xyz * 2 - 1;
#else
fixed3 normal;
normal.xy = packednormal.wy * 2 - 1;
normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
return normal;
#endif
}
- 노멀이 Z축이고 버텍스에서 UV의 U축을 X축으로하며 탄젠트 벡터인데,
유니티는 왼손좌표계로 내적시 나오는 방향이 바이탄젠트(또는 바이 노멀)
백터로 V축을 Y로 한다. 회전만 다루므로 아래 그림과 같은 매트릭스를 얻으며
축에 맞게 텍스처를 세팅하면 해당 픽셀에 노멀값을 읽을 수 있다.
![](https://velog.velcdn.com/images/kimpro/post/55b37fae-3d25-4d62-8e54-930fc65cc5a2/image.png)
- Lit 쉐이더의 경우 Nomral맵을 넣는 슬롯이 있지만 Unlit이라던가 다른
쉐이더의 경우 Normal맵 슬롯이 없어 직접 노멀맵을 제작해서 넣어줘야함.
Unlit은 보통 카툰렌더링과 같이 직접 빛을 조작하고 싶을때 사용.
Parallax Mapping
- HeightMap으로 높이값을 저장하여 노멀맵보다 더 깊이 정보를 제공
- 하지만 픽셀내에서 연산을 하기 때문에 외곽은 직선으로 보여진다.
- 인접한 픽셀간 높이차로 차폐를 확인하기 때문에 연산비용이 더 들어 가성비x
![](https://velog.velcdn.com/images/kimpro/post/5e588540-cdfe-480b-ba23-145df268123e/image.png)
- 텍셀 해상도에 제한을 받다보니 화면 움직여보면 지글지글하게 보임.
displacement Mapping
- Parallax와 달리 실제로 실제 버텍스를 조작하는데 테셀레이션으로 버텍스를
늘려주며 하드웨어 제약이 많아 모바일엔 적용이 안되는 경우가 많다.
- 실제로 버텍스는 움직이지 않고 픽셀내에서 하는것
- 그림자까지 만들면 성능이 더 필요하며, 음영이랑, 차폐정도로 보통 사용하며
모바일에서는 지금은 잘 사용하지 않는 편이다.
- 동일하게 HeightMap을 사용하거나 눈발자국같이 오브젝트 상호작용으로 테셀레이션
기타
- 백터의 내적을 할때는 cos을 사용할때 성능 이슈가 있으므로, 백터의 내적공식인 각 성분끼리 곱해서 더하면 내적이되므로 성능이 더 좋다.
- 유니티는 C#은 Column major 열기준 행렬이다. 쉐이더는 Case by Case 다르다.