WinCNT

Tonemapping Operator 본문

게임 프로그래밍(학습 내용 정리)/게임 수학

Tonemapping Operator

WinCNT_SSS 2022. 7. 26. 16:15

HDR로 만들어진 Data를 출력 가능한 형태인 LDR(혹은 SDR)로 바꾸는 연산

float를 byte로 바꾸는 연산이기 때문에 다양한 연산자(연산 방법)가 존재한다

LDR에선 당연히 사용 안 함

 

전체적으로 어두운 쪽에 값을 많이 표현하도록 되어 있는 그래프(로그 함수와 비슷)가 특징이다

이것은 웨버의 법칙을 반영했기 때문이다

웨버의 법칙은 사람의 눈이 어두운 부분에서는 밝기가 조금만 변해도 그 차이를 감지하는 반면
밝은 부분에서는 더 큰 변화가 있어도 그 차이를 잘 감지할 수 없는 특징을 말한다

 

다음은 다양한 톤 매핑 기법에 대한 설명이다

(출처는 글 마지막에 기재)

Reinhard

float4 Reinhard( float2 texCoord  : TEXCOORD0 ) : COLOR
{
    float3 texColor = tex2D(Texture0, texCoord );
    texColor *= g_fHardExposure;  // Hardcoded Exposure Adjustment
    texColor = texColor/(1+texColor);
    float3 retColor = pow(texColor,1/2.2);
    return float4(retColor,1);
}

Haarm-Peter Duiker's curve

룩 업 테이플이 필요한 것이 특징

float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
{
   float3 texColor = tex2D(Texture0, texCoord );
   texColor *= 16;  // Hardcoded Exposure Adjustment

   float3 ld = 0.002;
   float linReference = 0.18;
   float logReference = 444;
   float logGamma = 0.45;
      
   float3 LogColor;
   LogColor.rgb = (log10(0.4*texColor.rgb/linReference)/ld*logGamma + logReference)/1023.f;
   LogColor.rgb = saturate(LogColor.rgb);
      
   float FilmLutWidth = 256;
   float Padding = .5/FilmLutWidth;
      
   //  apply response lookup and color grading for target display
   float3 retColor;
   retColor.r = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.r), .5)).r;
   retColor.g = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.g), .5)).r;
   retColor.b = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.b), .5)).r;

   return float4(retColor,1);
}

 

Filmic(JimHejl)

float4 Filmic( float2 texCoord  : TEXCOORD0 ) : COLOR
{
    float3 texColor = tex2D(Texture0, texCoord ); // Tex Read
    texColor *= g_fHardExposure;  // Hardcoded Exposure Adjustment
    float3 x = max(0,texColor-0.004); // Filmic Curve
    float3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
    return float4(retColor,1);
}

언차티드2

언차티드2에 사용된 톤 매핑

float3 Uncharted2Kernel(float3 x)
{
    float A = 0.15;
    float B = 0.50;
    float C = 0.10;
    float D = 0.20;
    float E = 0.02;
    float F = 0.30;
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}

float4 Uncharted2( float2 texCoord  : TEXCOORD0 ) : COLOR
{
    float W = 11.2;
    float3 texColor = tex2D(Texture0, texCoord );
    texColor *= g_fHardExposure;  // Hardcoded Exposure Adjustment
     
    float ExposureBias = 2.0f;
    float3 curr = Uncharted2Kernel(ExposureBias*texColor);
     
    float3 whiteScale = 1.0f/Uncharted2Kernel(W);
    float3 color = curr*whiteScale;
     
    float3 retColor = pow(color,1/2.2);
    return float4(retColor,1);
}

 

참고 사이트

John Hable

 

http://filmicworlds.com/blog/filmic-tonemapping-operators/

 

Filmic Tonemapping Operators

The most common questions that I get about my GDC talk have to do with the tonemapping operators. In particular, I’ve always found that when I read through presentations for code snippets that I always miss something. Those 2.2s can be tricky! So this po

filmicworlds.com

The Danger Zone

 

https://therealmjp.github.io/posts/a-closer-look-at-tone-mapping/

 

A Closer Look At Tone Mapping

A few months ago my coworker showed me some slides from a presentation by tri-Ace regarding their game “Star Ocean 4”. The slides that really caught my eye were pages 90 to 96, where they discussed their approach to tone mapping. Instead of using the

therealmjp.github.io

SSS

'게임 프로그래밍(학습 내용 정리) > 게임 수학' 카테고리의 다른 글

Color Grading  (0) 2022.07.12
SSAO(Screen Space Ambient Occlusion)  (0) 2022.07.12
Texture Technique  (0) 2022.07.12
Illusion  (0) 2022.06.28
Edge Detect Filter  (0) 2022.06.28