着色过程中的伽马校正Gamma Correction

时间:2024-03-17 15:40:58

前言

       Gamma Correction在着色计算中非常重要。如果使用不当,可能会造成错误的渲染结果或导致渲染结果得不到正确的显示。

       本文将简要介绍Gamma Correction的基本原理及其在着色计算中的简单应用。

 

Gamma

      我们在日常生活中使用的显示器绝大多数都是非线性的。这个非线性的关系具体可以表示为

                                                                    clip_image002

其中x代表像素值,y代表显示器辐射亮度。指数是一个常量,叫做显示器的gamma值。

       Gamma值通常情况下可取2.22,这样就能得到像素值与显示器辐射亮度的关系曲线,如图1所示:

                                                 clip_image002[4]

                                                                                图1

       当像素值为(0.2,0.2,0.2)时,显示器辐射亮度为0.028。当我们想让显示器的辐射亮度变为之前的两倍时,此时的像素值应该为(0.27,0.27,0.27),而不是(0.4,0.4,0.4)。

 

Gamma Correction

       着色计算必须在线性空间中进行,其计算结果也是线性的。为了能将线性的计算结果显示在非线性的显示器上,必须对计算结果进行gamma校正。如图2所示

      clip_image002[6]

                                                                              图2

       仅对着色结果进行Gamma校正还不够。一般的纹理都是处于非线性空间的,因为这些纹理都是在非线性的显示器上绘制的。而着色计算需要在线性空间中进行,所以在纹理采样之后要将其转化到线性空间。

       综上所述,着色过程中需要两次转化:

1. 采样的纹理进行非线性(sRGB)到线性(Linear)的转化,记为sRGB->Linear

2. 着色计算的结果进行线性(Linear)到非线性(sRGB)的转化,记为Linear->sRGB

      下面举一个简单的例子说明这两次转化的重要性。在像素着色器中对纹理进行采样,然后将采样结果返回送入back buffer。图3中A对纹理进行了sRGB->Linear处理,对返回结果进行了Linear->sRGB处理,最终得到了正确的显示结果。B只对纹理进行了sRGB->Linear处理,导致显示结果偏暗。C只对返回结果进行了Linear->sRGB的处理,导致显示结果发白。

                clip_image002[8]

                                                               图3

 

Direct3D10

      纹理的sRGB->Linear和着色结果的Linear->sRGB均可由Direct3D10完成,不需要在着色器中转化。

 

       纹理sRGB->Linear:

1. 用D3DX10CreateTextureFromFile()创建纹理时,将D3DX10_IMAGE_LOAD_INFO结构体的          Format赋值为DXGI_FORMAT_R8G8B8A8_TYPELESS

2. 用CreateShaderResourceView()创建纹理视图时,将 D3D10_SHADER_RESOURCE_VIEW_DESC结构体的Format赋值为DXGI_FORMAT_R8G8B8A8_UNORM_SRGB

 

      返回值Linear->sRGB:

    在创建swap chain时,将DXGI_SWAP_CHAIN_DESC结构体中DXGI_MODE_DESC结构体的Format成员赋值为DXGI_FORMAT_R8G8B8A8_UNORM_SRGB。

 

进一步阅读

      [1] Gritz, Larry, and Eugene d’Eon, “The Importance of Being Linear”

            http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html

      [2] Hoffman, Naty, “Adventures with Gamma-Correct Rendering,” Renderwonk blog. 

            http://renderwonk.com/blog/index.php/archive/adventures-with-gamma-correct-rendering/

 

参考

      [1] “Real-Time Rendering(3rd)”