블로그 이미지
자신의 단점을 메꾸는 것을 단(鍛)이라 하고 자신의 강점을 갈고 닦는 것을 련(鍊)이라 하여, 두가지를 합친 것을 단련이라고 부른다. 붕대마음

카테고리

전체목록 (667)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (105)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (218)
유용한 것들_etc (44)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (1)
따라잡기 시리즈 (0)
링크용 (0)
Total344,974
Today26
Yesterday53

'압축'에 해당되는 글 2건

  1. 2016.06.13 normal map compression
  2. 2013.03.15 DXT 압축

보통 게임에서는 메모리 용량 때문에 텍스쳐를 압축해서 많이 사용하는데

pc에서는 특히 dds 파일을 많이 사용한다.

dds 파일 포멧을 많이 쓰는 이유는 "DXT 압축" 링크를 참조하면 된다.


그런데 문제는 DXT 압축 알고리즘이 노멀맵을 염두에 두고 설계한 것이 아니기 때문에 노멀맵에

DXT 압축을 사용하는것은 퀄리티에 심각한 결점을 부과해 준다는 것이다.


그래서 노멀맵은 어떻게 해야할까?

그렇다면 어떻게 해야 할까? dxt의 그 가성비를 포기해야 하는가?

다른 맵과는 다른 노멀맵의 특성을 이용하면 약간의 편법을 이용할 수 있다.

우선 노멀맵은 다른 텍스쳐들(diffuse, specular, emissive etc..)처럼 색의 정보를 저장하는게 아니라

기울기 정보, 즉 방향정보를 저장하고 있다.

이 기울기 정보를 저장하기 위해 기울어진 면에서 세개의 수직인 축을 저장하는데 이게 노멀맵이다.


여기에 DXT5 압축 알고리즘을 어떻게든 노멀맵에 적용시도를 해보자면...

dxt5의 경우 R5G6B5A8 픽셀포멧이며 unity에서 pc환경에서 노멀맵은 내부적 dxt5nm형식을 사용한다.

이 포맷은 dxt5와 형식이 같지만 압축하기 전에 red를 alpha로 옮기고 green은 그대로,

red와 blue는 단색으로 비우는데 이 작업을 보통 swizzling 라고 한다.

이는 데이터 손실을 최소화 하기 위함인데 dxt5 포맷의 바이트 배분이

5:6:5:8 (R:G:B:A) 이기 때문이다.

알파채널과 그린채널을 보면 Red나 Blue에 비해 비트수가 더 높은 것을 알 수 있다.

그래서 압축 전에 R값을 A로 옮겨서 데이터 손실을 최소화 하는 것이다.


UnityCG.cginc 파일을 보면 아래와 압축된 노멀맵을 압축해제하는 함수가 있다.

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;

}


첫번째 연산을 보면 노멀의 w(a)와 y(g)를 0~1 범위를 -1~1범위로 바꾸는 작업을 한다.

w에는 r값을 넣었고 y에는 g값을 넣어서 압축했으므로 두 채널의 값만 압축해제하면 된다.


그 후 x와 y값으로 normalized 된 normal 벡터의 z값을 복원하면 된다.

수직벡터 구하는 방법에 대한 내용은 아래 링크를 참고하면 된다.


그런데 왜 R과 B채널을 쓰지 않는것 만으로 압축품질이 더 좋아지는 걸까?

이는 DXT 압축이 이미지의 각 4x4블록에 대해 두 개의 기본 색상만 선택하여 수행되기 때문이다.

만약 블럭의 모든 색상이 이 두 끝점 사이의 선을 따라 있으면 압축 품질이 좋다.

최악의 아티팩트는 단일 블럭에 RGB공간을 통해 분산된 색상이 포함되어 있을 때 발생하므로 

하나의 선을 통과 할 수 없다.

b채널을 버림으로써 3차원 RGB 색상 곤간을 2차원 R/G공간으로 축소한다.

이렇게 하면 블럭의 모든 색상에 적합한 단일 선의 확률이 높아져 압축 퀄리티가 좋아진다.

더 나은 품질을 위해 위에서 설명한 대로 비트수가 높은 알파채널과 G채널을 사용하면 더 좋다.

이렇게 하면 압축에 대한 걱정거리가 하나의 색상 차원으로 남게되어 모든 블록이 단일 라인을 따라

잘 맞을 것이다.

그리고 그냥 DXT1 텍스쳐에 RG를 쓰고 B를 0으로 밀어버리는 것 만으로 pixel 연산을 희생양 삼아

퀄리티가 좀 더 좋아 질 수도 있다.

이는 정밀도는 같지만 압축 알고리즘상 색상 매칭 확률을 높이니 조금 더 부드러워 보일 수 있다.

이에 대한 내용은 이곳을 참조 하면 된다.



언리얼의 V8U8과 DXTnm은 같은가?

자료가 많지 않아서 잘 모르겠지만 DXTnm은 기본적으로 DXT5의 포맷을 사용하고,

V8U8과 같이 수직축 계산한다는 건 동일하지만 DXT5는 5658로 기본적으로 4채널을 사용하고

높은 비트로 채널을 옮기며, 안쓰는 채널을 0으로 하여 압축시 매칭비율을 높이는 방식을 사용한다.

즉, 정밀도를 조금 늘리기 + 수직축 계산하기 + 압축하기 의 작업인듯 하다.

V8U8은 그냥 처음부터 높은 정밀도로 2채널만 사용하고 압축은 하지 않으며 밉맵을 하나 낮춘다.

즉, 정밀도 많이 올리기 + 수직축 계산하기 + 용량 줄이기 위해 밉맵 낮추기.

V8U8은 알파와 휘도를 저장하기 위한 A8L8의 signed 버전인듯 하다.


그렇다면....

노멀맵을 저용량에 고퀄로 쓰고싶다.

-> DXT1 압축을 해보자, 저용량이지만 퀄리티가 망이다.

-> DXTnm 압축을 해보자, 저용량은 아니지만 퀄리티는 좀 좋아진다.

-> V8U8 비압축을 해보자, 저용량에 고퀄이지만 저용량으로 하기위해 해상도를 확대하면 

    쨍한 부분에서 계단현상이 생기긴 한다.


목표는....

V8U8의 용량과 고퀄을 유지하고 해상도에 대한 아티펙트를 줄여보자!!

이에대한 아이디어는 나온게 꽤 많으니까 하나씩 적용해 보자!!



https://www.garagegames.com/community/blogs/view/22776



Reference Link

- Normal, Tangent, BiTagent Vector 그리고 Unity Normal Map

- dxt 압축

- 디더링

- 픽셀 셰이더 프로그래밍


- 유니티 엔진의 노말맵은 노랑색? 흑백? 파랑색?

DXT compression for normalmaps

- 수직벡터 구하는 방법

- unreal, V8U8

- Texture Compression Techniques and Tips

Real Time DXT Compression.pdf

ati NormalMapCompression.pdf

- nvidia, Real Time Normal Map DXT Compression

- unreal, 노말맵 제작기법

- normal editing tip


'Study > Graphics' 카테고리의 다른 글

Blur 1  (0) 2016.10.12
UV Texture Coordinates and Texture Mapping - OpenGL / DirectX  (0) 2016.08.14
normal map compression  (0) 2016.06.13
Semantics  (0) 2016.05.09
normal mapping artifacts  (0) 2014.12.10
tangent space, 접선 공간  (0) 2014.04.07
Posted by 붕대마음

댓글을 달아 주세요

DXT 압축

Study/Graphics / 2013. 3. 15. 17:08
우선 기본적으로 PC게임에서 DXT(DirectX Texture) 픽셀 포맷을 많이 사용한다.
이 DXT 포맷은 Direct3D API 표준이며 이름 또한 DirectX Texture 이다.
그렇다면 이 DXT는 어떤 장점이 있고 어떤 특성이 있기에 DX에서 표준이 되었을까?


DXT픽셀 포맷을 저장하는데 사용되는 DDS 파일포맷이란 무었인가?
DDS(DirectDraw Surface)
이 파일 포멧은 텍스쳐 매핑과 큐브맵 환경맵을 저장하는데 쓰이는 마이크로스프트사의 포멧이며,
GPU에 쓰이는 DXTn으로 압축된 데이터를 저장하는데 유용하다.
이 파일 포멧은  DirectX 7.0에 도입되었으며 원래 DirectX를 위해 설계되었으며 밉맵,
큐브맵, 볼륨맵을 지원한다.
이 파일 포맷은 압축 및 비압축 픽셀 형식을 저장할 수 있으며 PC게임에서 DXTn 압축 픽셀 포맷을
저장하기위해 주로 사용한다.
추가 설명은 Programming Guide for DDS를 참조하면 된다.


DXT를 쓰는 이유는?
1. 압축률이 높다 : 메모리를 적게쓴다.
2. 성능저하가 거의 없다. : 거의 모든 그래픽 카드가 하드웨어 레벨에서 DXT포맷을 지원한다.
3. 퀄리티가 나름 괜찮다. (그라데이션있는 텍스쳐나 노말 텍스쳐에는 비츄)



DXT 압축 방식은?
DXT(DirectX Texture)는 소프트웨어 기반의 경량 압축기법으로 각 프레임 내에서 독립적인 4x4픽셀 블록 단위로 
손실압축을 수행하며 압축비율은 4:1~8:1로 고정되어 있다.

DXT1의 기본 압축 알고리즘을 살펴보면 아래와 같은 순서로 진행된다.
1. 압축할 원본 이미지에서 4x4 픽셀 블록을 추출한다.   
   - 한 텍셀 read시 해당 텍셀이 포함된 16픽셀이 내부 비디오 캐시로 이동.
   - 실제 렌더링시 Bilinear Filtering등 아주 근접한 텍스처를 읽어들이는 경향이 있음
   - 렌더링 특성상 연속된 텍셀을 읽어들이는 경향이 있다.
   - 다음에 해당 블럭 중에서 읽어들일 확률이 매우 높다. (Cache hit)

2. 픽셀 블록의 16개의 픽셀 중에서 최대값(흰색에 가까운 색)과 최소값(검은색에 가까운 색)을 구한다.
   DXT압축으로 표현되는 색 해상도는 16비트(High Color, R5G6B5)이므로 24비트(R8G8B8) 색 해상도를
   가지는 이미지는 16비트 색 해상도로 변환한다.
   따라서 최대값(Color 0)과 최소값(Color 1)의 색 해상도를 변환(R5G6B5)하고 
   중간값 2개(Color2, Color3)를   계산한다.

이미지 참조 : http://kiise.or.kr/e_journal/2012/8/cpl/pdf/01.pdf

  2개의 색상값(최대R5G6B5, 최소R5G6B5)을 저장하기 위해 필요한 32bit와 이 두 색상값에 대한

  16개의 2BIT 인덱싱을 저장한다.

  EX : 

  - 00 이라면 최대값

  - 01이라면 최소값

  - 10이라면 2/3 * 최대값 + 1/3 * 최소값

  - 01이라면 1/3 * 최대값 + 2/3 * 최소값

  이렇게 해서 색상값 2개 32bit와 인덱싱값 16개 32bit를 합쳐서 총 64bit가 된다.

  dxt1 압축을 기준으로 24비트(R8G8B8) 텍스쳐의 경우 4x4 사이즈라면 3byte * 16 = 48byte가 필요하지만 

  dxt1 압축을 하면 64bit 즉, 8byte가 필요하다.


이를 이미지로 표현하면 아래와 같다.

이미지 참조 : https://www.slideshare.net/zho7611/ndc2012-12677111





Reference Link


'Study > Graphics' 카테고리의 다른 글

normal mapping artifacts  (0) 2014.12.10
tangent space, 접선 공간  (0) 2014.04.07
DXT 압축  (0) 2013.03.15
BRDF (Bidrectional Reflectance Distributing Function)  (0) 2012.12.06
64박스 필터 샘플링  (0) 2012.01.30
9콘 필터 샘플링  (0) 2012.01.26
Posted by 붕대마음

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함