Gamma-Correct Rendering(翻譯)


隨着消費類硬件能夠渲染渲染高動態範圍圖像數據,(進入)8位sRGB幀緩衝區的時代越來越近了。下一代圖形設備的編程人員能夠對照明系統進行高精度建模,然後將這些值映射到常規8位sRGB設備(例如PC顯示器)的可顯示範圍內。[注:原文寫於2004年,年代久遠,開場白看看就好。]

從源圖像到最終輸出圖形的轉換過程非常複雜,並且需要程序員在不同的顏色空間中處理。在這篇文章中,我將會簡要介紹顏色空間,然後詳細介紹轉換過程中一個通常被忽略但依然很重要的地方,那就是gamma函數。

sRGB標準

sRGB的色彩空間是根據昏暗環境工作條件下辦公室的顯示器特性而設計的,並已由IEC (IEC 61966-1-2)標準化。該色彩空間已被業界廣泛採用,廣泛應用於CRT、LCD、投影儀等領域。現代8位圖像文件格式(如jpeg2000或PNG)默認爲sRGB顏色空間。

sRGB顏色空間中的值是一個浮點三元數組,每個值在0.0到1.0之間。 超出此範圍的值將被裁剪。這些sRGB顏色值通常會被編碼爲0到255之間的8位無符號整數。

關於sRGB,關鍵要記住它是非線性的。 它大致遵循曲線 y = x ^2.2 ,實際的標準曲線稍微複雜一些。 sRGB與gamma 2.2的關係圖如下所示:

顏色空間對比

此映射具有很好的特性,低亮度RGB值具有更高的分辨率,非常適合人類的視覺模型。

Gamma函數作爲近似值

從上圖可以看出,sRGB標準非常接近Gamma2.2曲線。 因此,完整的sRGB轉換功能通常用更簡單的Gamma函數來近似。

請注意,與單詞Gamma關聯的值是函數y = x ^ p 中使用的冪值。 不幸的是,Gamma通常與亮度有關,而Gamma與亮度並不完全相同。完整的0-1區間始終映射回完整的0-1區間 [注:這裏的意思可能是把[0,255]映射回[0,1]]。

這個顏色空間用到了什麼樣的數學?

通常,你的照明處理過程應在線性空間中進行,以便所有照明都是線性累積的。這是許多下一代引擎中採用的方法,也是確保你的物理正確性的唯一方法。

但是,假設Gamma函數近似值足夠好,你仍然可以執行調整操作。 在這種情況下,我們有一些常數A,希望使用它來調整sRGB源數據x,並將結果存儲在sRGB中作爲y。 在線性空間中,可以這樣寫:

 y ^{2.2}=Ax^{2.2}=\left [ A^{\frac{1}{2.2}}x \right ]^{2.2}

由於我們只在0-1區間內工作,所以我們可以在sRGB工作空間內把兩邊的指數約掉。得到:

 y =A^{\frac{1}{2.2}}x

因此,如果我們將常量轉換進sRGB,調整運算依然可行。 但是,只有極少數的運算可以用這種方式進行。加法運算(用於加法照明模型或用於alpha混合)不能爲工作在gamma 2.2空間而重新制定,因爲這個空間是非線性的。如果你希望有一個正確的可加照明模型,則必須在線性空間中工作,這意味着你需要一個高精度的幀緩衝區以至少匹配sRGB的低亮度粒度。

一個sRGB示例:Mip映射

如果在sRGB顏色空間中對圖像進行雙線性過濾,則最終總是會得到比正確結果更暗的過濾顏色。錯誤量隨着輸入顏色範圍的增加而增加。這是黑白網格經過過濾且不進行顏色空間轉換的最壞情況的示例:

中心圖像包含交替的黑白線。 左圖像和右圖像是通過對圖像進行降採樣,然後按比例放大回原始大小而生成的。 左圖是在線性空間中進行降採樣,右圖是直接在sRGB中進行降採樣。

在標準照明條件下經過正確校準的監視器上,左側圖像和中央圖像應顯示相同的整體亮度。 這是因爲線性空間平均值爲50%灰色,它在sRGB中被映射爲186的值。 右側圖像的sRGB值爲128,但是在線性空間中只有21.4%的灰色,因此應顯得更暗。

大多數遊戲材質的亮度變化都沒有那麼高,因此直接過濾sRGB顏色引入的錯誤遠沒有本示例中那麼嚴重。 但是,在將每個Mip級別保存到sRGB中之前,應將任何高變化數據(例如預先計算的光照貼圖)過濾爲線性光照值。

總結

當代的圖形硬件可以在材質讀取指令期間將數據從sRGB移動到線性空間,並且假設你使用了高精度的幀緩衝區,那麼將最終的渲染轉換回sRGB以在顯示設備上使用的成本很低。 在工具中,我們將更多的精力放在正確性上,因此可以忽略在色彩空間之間移動所需的額外轉換時間。

期望下一代渲染引擎能夠正確模擬複雜照明方程式的所有微妙之處,因此在整個藝術流程和渲染系統中必須對色彩空間有所瞭解是至關重要的。 希望本文讓大家瞭解了色彩空間非常重要的區域。下一部分包含了我在美術工具和渲染代碼中都使用過的一些轉換方程式。

相關公式

sRGB to linear RGB: rgb (sRGB), RGB (linear RGB)

\begin{align*} R &= \begin{cases} r/12.92, &r \leq 0.04045 \\ ((r + 0.055)/1.055)^{2.4}, &r > 0.04045 \end{cases} \\ G &= \begin{cases} g/12.92, &g \leq 0.04045 \\ ((g + 0.055)/1.055)^{2.4}, &g > 0.04045 \end{cases} \\ B &= \begin{cases} b/12.92, &b \leq 0.04045 \\ ((b + 0.055)/1.055)^{2.4}, &b > 0.04045 \end{cases} \\ \end{align*}

一般而言,上式近似地作爲計算X = x^{2.2} 的值,應用於所有通道。

linear RGB to sRGB: RGB (linear RGB), rgb (sRGB)

\begin{align*} r &= \begin{cases} 12.92 R, &R \leq 0.0031308 \\ 1.055 R^{1.0/2.4} - 0.055, &R > 0.0031308 \end{cases} \\ g &= \begin{cases} 12.92 G, &G \leq 0.0031308 \\ 1.055 G^{1.0/2.4} - 0.055, &G > 0.0031308 \end{cases} \\ b &= \begin{cases} 12.92 B, &B \leq 0.0031308 \\ 1.055 B^{1.0/2.4} - 0.055, &B > 0.0031308 \end{cases} \end{align*}

一般而言,上式近似地作爲計算x = X^{1/2.2} 的值,應用於所有通道。

XYZ to linear RGB: (D65 white point)

\begin{align*} R &= 3.2406 X - 1.5372 Y - 0.4986 Z \\ G &= -0.9689 X + 1.8758 Y + 0.0416 Z \\ B &= 0.0557 X - 0.2040 Y + 1.0570 Z \end{align*}

linear RGB to XYZ: (D65 white point)

\begin{align*} X &= 0.4124 R + 0.3576 G + 0.1805 B \\ Y &= 0.2126 R + 0.7152 G + 0.0722 B \\ Z &= 0.0193 R + 0.1192 G + 0.9505 B \end{align*}

[注:這裏的D65是指CIE標準光源]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章