Vertex Component Packing 처리에 이어서, normalmap도 압축을...
NVIDIA에서 제공하는 Real-Time Normal Map DXT Compression를 많이들 읽어보셨겠지만, 아직 못 본 사람(저요.. ㅡㅡ;;)들을 위해서, 소개합니다.
최근 보고 있는 Nebula3에서는 DXT5nm으로 사용하는 것이 기본으로 되어 있는데요.(photoshop dds plug-in 등을 이용해서, .tga등의 노말맵을 DXT5nm 형식으로 저장하는 것을 의미하겠죠). 대략 DXT5nm의 내용은 압축을 하면, Quality를 높이기 위해, x, y만 저장해서 사용하고, 높이값은 계산해서 구하자는 것입니다.(요즘 게임에 가장 대중적으로 사용된다는군요.)
# input.x = 0
# input.y = normal.y
[0, 1]
# input.z = 0
# input.w = normal.x
[0, 1]
Shader 안에서 decompress 하는 코드는 Nebula3에 있는 것을 보자면, 아래와 같습니다.
// DXT5nm -> tangentSurfaceNormal 구하기
float3 SampleNormal(sampler bumpSampler, float2 uv)
{
float3 n;
n.xy = (tex2D(bumpSampler, uv).ag * 2.0) - 1.0;
n.z = sqrt(1.0 - dot(n.xy, n.xy));
return n;
}
결과적으로, 약간의 오차는 느껴집니다만, 2048x2048 Texture(.tga)가 대략 16.4m인데 비해, dds로 압축하면, 5.4m(mipmap포함)이니, 상당한 절약이 되는군요...
(개인적으로 왠만치 가까이 가지 않는 이상 잘 느껴지지도 않는뎁쇼?!)
참고로, HALO도 DXT5로 압축을 하여 사용했다고 Halo3문서에 소개가 되어있다네요.
NVIDIA에서 제공하는 Real-Time Normal Map DXT Compression를 많이들 읽어보셨겠지만, 아직 못 본 사람(저요.. ㅡㅡ;;)들을 위해서, 소개합니다.
최근 보고 있는 Nebula3에서는 DXT5nm으로 사용하는 것이 기본으로 되어 있는데요.(
# input.x = 0
# input.y = normal.y
[0, 1]# input.z = 0
# input.w = normal.x
[0, 1]Shader 안에서 decompress 하는 코드는 Nebula3에 있는 것을 보자면, 아래와 같습니다.
// DXT5nm -> tangentSurfaceNormal 구하기
float3 SampleNormal(sampler bumpSampler, float2 uv)
{
float3 n;
n.xy = (tex2D(bumpSampler, uv).ag * 2.0) - 1.0;
n.z = sqrt(1.0 - dot(n.xy, n.xy));
return n;
}
결과적으로, 약간의 오차는 느껴집니다만, 2048x2048 Texture(.tga)가 대략 16.4m인데 비해, dds로 압축하면, 5.4m(mipmap포함)이니, 상당한 절약이 되는군요...
(개인적으로 왠만치 가까이 가지 않는 이상 잘 느껴지지도 않는뎁쇼?!)
참고로, HALO도 DXT5로 압축을 하여 사용했다고 Halo3문서에 소개가 되어있다네요.





덧글
kjmgo 2009/05/07 15:32 # 삭제 답글
이번 프로젝트때, normal map을 쓰려고 하는데 좋은 참고가 되겠네요^^좋은 자료 감사합니다~
cagetu 2009/05/07 18:10 #
훌륭한 그림 기대할게요.. ^^
kimsama 2009/05/11 11:52 # 답글
shaderx 2권에도 노말맵 압축과 관련한 "Normalmap Compression", Jakub Klarowicz의 글이 있습니다.
cagetu 2009/05/11 21:43 #
네, 그 글도 읽어봤는데, 거의 nvida 문서에 총정리되어 있는 듯 합니다. ^^