Colin_BarreBrisebois_Programming_ApproximatingTranslucency

Download Report

Transcript Colin_BarreBrisebois_Programming_ApproximatingTranslucency

http://www.kindnap.pe.kr
http://cafe.naver.com/shader
The Importance of Being Linear
 그래픽스 하드웨어의 발달로 사실정인 조명과 음영을
실시간으로 얻을 수 있는데,
 이중에서 적절한 감마 보정은?
 아마도 정말 쉽고,
 저렴하면
 실시간으로 귀하의 프로그램에 이미지 품질을
향상 시키는데 큰 도움이 될 것이다.
 적용 또한 간단합니다.
그래픽스 에서 감마(GAMMA)란?
 그래픽스 전반적으로 많이 쓰이는 용어입니다.
 ‘비선형’이란것이 핵심!




어떤 특성의 비선형의 띄면서 그것을 감마곡선이라고 한다.
자동제어 이론에서 사용하는 일종의 함수라네요…
윈도우 API에서 지원하는 함수 그래픽 카드가 호출하는 감
마곡선을 변환시킬수 있다.
 SetDeviceGammaRamp
 GetDeviceGammaRamp
다이렉트 X에서는 SetGammaRamp라는 메쏘드로 위의 함수
와 같은 동작함
감마(GAMMA)란?
 모니터 자체 내에도 감마 곡선이 존재한다.
 그래픽 어댑터에도 감마 곡선이 존재한다.
 그런데 포토샵에서도 감마 곡선이 존재한다??
 왜 감마곡선이 필요한거야?
감마(GAMMA)란?
 우선 우리의 눈 자체가 비선형적인 특징을 보인다.
 당신이 책상위에 앉아 있고, 빨간색 색종이를 바라보고 있다고 치자..
이때.. 주의 밝기를 선형적으로 변화시켜보자..
당신이 바라보고 있는 빨간색 색종이의 색도 선형적으로 변화되며 보일까?
 절대 그렇지 않다. 라고.. 누군가 실험했단다. -_-;
 이게 비선형적인 특징이다.
 선형적이라고 하면
 1을 입력으로 주었을때.. 1이 나왔고
 2를 입력으로 주었을때.. 2가 나왔다면..
 3을 입력으로 주었을때.. 3이 나와야.. 선형 시스템이고..
 감마 보정이고 뭐고 필요가 없는 것이다.
감마(GAMMA)란?
 모니터를 구입할 때 보면 이것 말고도 비슷한 용어들이 많
다. (감마보정, 휘도보정, 색온도 비싼 것들일수록 모니터
자체에서만 조정할수 있는것들이 많아진다.)
 이러한 것들이 있는 궁극정인 목적인
 전체 화면의 휘도가 똑같아 지기 위함이라고한다.
 이게 고급기술! 비싼기술!이라고 합니다.
 화면의 좌상단과, 중간, 우상단의 휘도가 우리의 눈으로 구별
하긴 쉽지 않지만 저가형일수록 같지 않다고 한다.
 좋은 모니터로 멀티비전 구성한다면 위화감이 없다고…
감마(GAMMA)란?
 방송없을때 나오던
화면조정시간 화면은 그냥 나오는 것이 아니었습니다!
감마(GAMMA)란?
 실제로 화질 조정에 대한 자격증도 있다.
 외국에선 한번 화질 맞추어줄 때마다
상당한 금액을 지불한다.
 바로 이것이 고급 기술이고, 비싼 기술이다.
 하지만 막눈인 나에겐 의미가 없는듯…
 화질 좋은 제품이 어디게 있냐고 물어봤더니..
 파라소닉이 제일 좋덴다..
 소니는 끼긴 했는데 안좋다라는 평가를 내리고..
 삼성과 LG는 언급 자체도 안했다. -_-;
Renderers Are Linear
 당신이 작업하는 Renderers는 칼라값을 선형적으로
쓰고 있진 않나요?
 모니터는 비선형적인데!!
 자신이 구현중인 엔진에서
택스쳐만 랜더링시
실제보다 어두워보인다면
의심해봐야 합니다!
Renderers Are Linear
 모든 모니터가 같은 감마 지수를 가지지는 않습니다.
 일반적으로 그것을 2.0 범위에서 2.4입니다.
 이 비선형 특성의 조절 효과에 대한
감마 보정이라고합니다.
Renderers Are Linear
보정후
/
보정전
Nonlinear Input Textures
 택스쳐들은 이미 precorrected 합니다.
 RAW 로 저장되는 형식은 조절할수 있는 값을 가진다고
하네요
 특히 모든 JPEG 파일은 2.2 감마에 대한 precorrected
 그러므로 랜더러에서 선형적으로 읽어와 이용할 수
있다고 생각해선 XX
Color
 감마보정은 칼라값에만 적용되는 내용입니다.
 게임 리소스로서 택스쳐는 칼라값만이 아닌,
Alpha channels, normal maps, displacement values
등을 기입하는 경우가 많은데, 이는 이미 선형적이라
는 것을 전제로 기입되는 값들이므로 감마보정이 필요
치 X.
NVIDIA GeForce 8-class(and future)
 GPUs support sRGB texture formats
 DX10 카드에서는 텍스쳐를 GPU 쪽으로 로딩할때 linear
space 로 자동 변환되게 할 수 있다. (변환될 때 색 손실
을 막기 위해 채널 당 8bit 이미지가 내부적으로 12bit 나
16bit 로 저장된다고 한다)
 Alpha values are not gamma-corrected when sRGB
buffers are enabled.
 로딩 타임에 변환되므로 텍스쳐 필터링도 linear space
에서 하게 된다. (이미 감마보정에 대한 처리의 의미인
듯)
 프레임 버퍼에 기입할때 또한 하드웨어에서 지원되어
처리된다.
DX9 / DX10
 DX10으로 Renderer를 구성한다 해도 하위버전 호환을 위
해 DX9랜더러를 만들어야만 한다.(Xp사용자가 절대적으
로 많으므로)
 DX10이 자동적으로 감마보정이 되는 sRGB포맷을 지원한
다고 사용하면, DX9으로 만든 랜더에서와 출력칼라가 분
명히 틀려지고 문제가 발생한다.
 DX9 / DX10 출력칼러를 통합하려면
 DX10을 버퍼를 sRGB를 사용하지 않고 RGB를 사용 하거나,
 DX9 에서 감마보정을 해줘야 한다.
 R8G8B8 버퍼
 R8G8B8_S
Manually Converting
Color Values to a Linear Space
 float3 diffuseCol =
pow( f3tex2D( diffTex, texCoord ), 2.2 );
Or (cheaper, but assuming gamma of 2.0 rather than 2.2)
 float3 diffuseCol =
f3tex2D( diffTex, texCoord );
 fuseCol = diffuseCol * diffuseCol;
Last-Stage-Output
Gamma Correction
 float3 finalCol =
do_all_lighting_and_shading();
 float pixelAlpha =
compute_pixel_alpha();
 return float4(pow(finalCol, 1.0 / 2.2), pixelAlpha);
 // Or (cheaper, but assuming gamma of 2.0 rather than 2.2)
return float4( sqrt( finalCol ), pixelAlpha );
Gamma Correction
 UDK에도 비슷한 내용이 적용되있다고 합니다.
 DX10을 RGB를 쓸 것이 아니라 DX9 감마 보정하는 방식
으로
Test code
 //Gamma Control Set Gamma value
 vTexDiffuse.rgb =
 pow(abs(vTexDiffuse.rgb), 2.2f) * vTexDiffuse.rgb;
 vTexDiffuse1.rgb =
 pow(abs(vTexDiffuse1.rgb), 2.2f) * vTexDiffuse1.rgb;
 vTexDiffuse2.rgb =
 pow(abs(vTexDiffuse2.rgb), 2.2f) * vTexDiffuse2.rgb;
 vTexDiffuse3.rgb =
 pow(abs(vTexDiffuse3.rgb), 2.2f) * vTexDiffuse3.rgb;
 vTexDiffuse.rgb = lerp( vTexDiffuse.rgb, vTexDiffuse1.rgb, vSpWeight.x );
 vTexDiffuse.rgb = lerp( vTexDiffuse.rgb, vTexDiffuse2.rgb, vSpWeight.y );
 vTexDiffuse.rgb = lerp( vTexDiffuse.rgb, vTexDiffuse3.rgb, vSpWeight.z );


PS_RenderOutput_2 o;
o.f40 = float4( pow( abs(o.f40.rgb), 1.0f/2.2f), 1.0f );

//Run Gamma value

vTexDiffuse = float4( pow( abs(vTexDiffuse.rgb), 1.0f/2.2f), 1.0f );


vTexDiffuse.rgb = /* vTexDiffuse.rgb * */ pow(abs(vTexDiffuse.rgb), 2.2f);
o.f40 = float4( pow( abs(o.f40.rgb), 1.0f/2.5f), 1.0f );
참고자료
 http://en.wikipedia.org/wiki/Gamma_correction
 http://jufoot.egloos.com/1960058
 http://cagetu.egloos.com/5148378
 http://www1.devpia.com/Maeul/Contents/Detail.aspx
?BoardID=51&MAEULNO=20&no=8350&page=1
Conclusion
 위에선 2.2 감마지수를 기준으로 표현했지만 자신이
개발한 프로그램에 알맞은 지수를 찻아라.
 NVIDIA GeForce 8-class(and future)를 사용한다면
기능을 활용해라
 감마보정은 칼라 값에만 적용되는 내용이다.