2009/10/09

Gamma correction and Linear workfkow 伽瑪校正與線性工作流程


VRay算出來的效果圖

譯者序:
上圖左是用不正確的Gamma算出來的效果圖,右圖是在正確的Gamma環境調出的結果. VRay在預設的狀況很容易算出艷麗飽和的色調 這樣的色調跟mental ray的細緻的清色調有很大的差別. 其實色調感的關鍵是gamma, 反而不是渲染器本身.

伽瑪(Gamma)是舊時代的產物 由於當時CRT螢幕輸入一單位電壓並不會產生等量的亮度(非線性) 所以為了正確顯示畫面 就刻意產生一個曲線關係(輸入與輸入) 讓最終輸出的影像為線性影像. 即使是現代 能夠製造出線性反應的螢幕(例如液晶) 這種現象仍然深深的影響影像處理 不管是後至合成調色 或是3D算圖渲染.

過去因為數位相機拍攝的影像因為一定會放在螢幕上觀看 而數位相機發展的年代 當時仍然是CRT 所以數位相機會自動在照片中內嵌Gamma的資訊 讓照片能正常地顯示在CRT螢幕. 然而到現代這反而成為一個大問題 因為所有渲染引擎VRay, mental ray, Finalrender, Maxwell,..都是以線性環境來計算物體與光的反應 所以如果輸入一個帶有Gamma資訊的貼圖 會造成輸出影像的錯誤(誤差) 甚至產生某種色彩調性(比方說VRay似乎比mental ray更艷麗)的誤解.


mental ray算出來的效果圖

這裡翻譯了幾篇不同來源的文章, 可以把趁機會把觀念搞懂 因為線性工作流程(linear workflow)是未來的趨勢. 當浮點運算(16或32bit)的後製剪輯軟體變成主流時 每個專業領域的人每天都會與LDR, HDR, Gamma這些東西搏鬥.

這是Autodesk 3ds max 2010 Help裡面的說明圖 這個流程幾乎把所有觀念都講到了, 關鍵在於在你餵給算圖器(renderer)圖檔之前 一定要把圖檔改為線性資料 這時圖檔就能夠在算圖器這個黑盒子中以正確的數學式計算結果 最後在輸出的時候即使結果是正確的 你沒有調整到跟螢幕相對的gamma值 那也會看起來是錯的影像!

---以下文章翻譯自MY MENTAL RAY網站---
標題: Gamma


伽瑪校正(Gamma correction)是一個經常被誤解的觀念。簡單來說,伽瑪描述了相機或螢幕的非線性反應的現象。當一個相機(模擬或數字)接收到兩倍的光源時,相機並不會把這個資料存成兩倍的RGB數值。有很多原因為什麼相機的記錄系統會有這種記錄方式----這種現象稱為伽瑪。其中一個原因是顯示器感光本身的問題,例如底片具有非線性的感光曲線,另外CRT螢幕也有同樣問題:像素的亮度跟輸入的電壓強度並不是呈現線性關係。

另外一個原因,因為人眼對於黑暗中的細節比明亮中的細節還要更敏感(人眼的感光曲線其實是對數曲線,稱為Weber-Fechner定律)所以人眼視覺是以非線性的方式記錄訊號的。而現代液晶顯示器(TFT)本身雖然沒有先天上的伽瑪問題, 但是為了要迎合傳統的工作流程 TFT螢幕會刻意模擬出伽瑪的效果。

建議讀者也可以讀讀這篇關於線性色彩空間 你就會知道位何在處理HDRI資料時伽瑪校正的重要性。如果你仍然不明白正確處理伽瑪是很重要的,請繼續往下讀。

伽瑪的基本觀念(Gamma 101)
  1. 所有的螢幕都有非線性的輸出輸入反應。這是故意的.
  2. 大多數的2D軟體都會以線性的顏色模型來處理,所以它假定,255數值的亮度是128數值的兩倍。但由於顯示器對於訊號的輸出輸入是非線性的,所以產生的亮度會是不正確的。事實上,大多數螢幕(gamma=2.2),如果你想要顯示出255數值亮度的50%亮度的話 那你就必須要輸入(0.5 ^(1/2.2))* 255 = 186的數值。如果你不考慮gamma的問題 輸入128數值 就只會產生大約(128/255)^ 2.2 = 22%的亮度。
  3. 數位相機基本上具有線性的輸出入效果,但因為通常我們會在電腦螢幕上面看拍出來的照片,所以數位相機會故意在照片裡面嵌入gamma。 (所以。JPG格式是帶有gamma的,但是RAW的格式是即線性資料,當你把RAW檔轉成JPG格式時就會產生非線性的照片了)
  4. 因此,如果你用2D軟體去開你照片拍出的jpg圖檔時,您必須要把gamma補償回來(去gamma)。
  5. 如果你的圖片是在2D軟體產生的(基本上這張圖是線性的),當你把這張照片顯示在帶伽瑪的螢幕 你也要做gamma補償。
更多關於伽瑪
  • Gamma不是bug,它是一個功能,因為人的眼睛對光線的亮度具有非線性的感光反應。如果你每個顏色只有8 bit來記錄顏色資料,很重要地利用這8 bit正確地重現人眼的感光效果很重要 它必須要是非線性的編碼方式。即使是新一點的螢幕仍然有伽瑪:同常顯卡會用8位元來處理每種顏色避免色帶問題,這8位元必須每個強度看起來間距是等距的。螢幕的廠商有能力製造線性反應曲線的螢幕,但如果你用8位元來顯示圖片,效果會很糟。
  • 現今大多數電腦螢幕都以sRGB的標準來顯示,也就是伽馬2.2。
  • 大多數數位相機也以sRGB紀錄相片。如果是掃描進來的圖或是合成圖像就不會帶有伽馬2.2。
  • 幾乎所有的浮點紀錄HDR資料是線性的,即與伽瑪為1.0。
  • 對於圖片而言,“伽馬”代表了強度是如何被記錄的。換句話說:圖檔的gamma是為了要讓圖片在螢幕上能正確地顯示出來。
  • 有些圖片會帶有gamma的標籤,但這是不可靠的,因為很多繪圖軟體會忽略這個標籤。因此,要正確知道圖檔的gamma數值並不容易。
  • 如果您的螢幕有2.2的伽瑪而顯示的圖片看起來有很正常,那該圖片可能本身就帶有伽瑪2.2。
  • 3D算圖引擎會假定光線是以線性的模式來記錄。所以,你丟給算圖引擎任何不是線性紀錄的圖檔(帶有gamma),嚴格說起來這個圖檔呈現出的效果是錯誤的(儘管它可能仍然好看)。
  • 請注意,NVIDIA顯卡驅動程式把gamma複雜性隱藏起來,當你在NVIDIA控制面板中看到:“1.0”,其實就代表是伽瑪2.2。因此,“NVIDIA公司的γ= 1.0”,其實是標準的sRGB伽瑪2.2

什麼時候忽略gamma問題時會產生恐怖的錯誤

基本上當你要去編輯像素混合時就會有差。例如:
  • 反鋸齒,特別是在做wireframe渲染或是渲染有高對比的影像
  • 縮小圖片。所以,高對比度的影像,會產生更明顯的錯誤
  • 半透明物體
Gamma in 3ds Max
在Preferences選單中可以控制伽瑪。基本上有三個伽瑪值可以調:
  • 顯示描述了您顯示器的  gamma 通常,這個會設定成2.2。
  • 當讀取貼圖時自動載入Gamma。這個功能能把圖片線性化(譯注:去gamma)。通常,這個有設定為2.2。 注意:如果您打開一張圖檔,這張圖檔嵌入伽瑪資訊,3ds Max會套用固定的gamma數值,而不是用你圖檔的gamma數值!當然你可以改變這個設定 當你開啟圖檔的時候。
  • 輸出伽馬會處理當你儲存圖檔時。這數值應該是1.0,如果你要儲存線性浮點圖檔格式。如果你只是希望這張圖檔再螢幕顯示,那就用2.2吧。
當您打開一張bitmap圖檔 而這張圖檔內嵌gamma,當你開啟圖檔時 你可以選擇是要套用通用gamma數值 還是要讀取圖檔的gamma。有一點很重要的是 bump 或 displacement貼圖你gamma一定要設定為1.0 因為這些是線性資料!

請注意,一些舊的3ds Max算法已調整為“好看”不伽瑪校正,並因此將看起來很有趣,如果你正確的伽瑪。

render farm會遇到的伽瑪問題
  • 當你的render slaves(算圖奴工)不認識你送出的max場景檔裡面的gamma資料時 算圖就會出現問題 所以 你可以在每台算圖奴工中設定respect the gamma state 這樣當讀到max場景檔時就會自動載入gamma。
  • 在3ds Max 2009當中使用分散式算圖Distributed Bucket Rendering (DBR)會有某個bug, 他會強制載入固定的nput Gamma. 這是因為分散式算圖會自動啟動mr Map Manager 它會忽略"per bitmap" gamma的設定, 所以 當你在場景中有使用HDR檔案 HDR會受到gamma=2.2影響 所以最後會產生太暗的影像 目前解決的辦法是將global input gamma設為1.0 然後使用mr's "Utility Gamma/Gain" shader把貼圖去gamma.
伽瑪常被誤解的觀念

錯誤觀念: 我已經校正螢幕了-所以我不需要管gamma
錯。當你校正完螢幕,通常代表你校準到標準的sRGB曲線,通常會是伽瑪2.2。當你的螢幕做過校正,這表示你的所有圖檔都必須要做伽瑪2.2的補償

錯誤觀念: 我的數位相機會記錄“線性”的照片
有可能 你如果是用RAW檔來存檔的話 它是線性格式沒錯。但當你把RAW檔轉成JPG格式時就會自動套用gamma,通常這個數值是2.2


---以下文章翻譯自MY MENTAL RAY網站---
作者是: Zap Anderson (mental ray作者之一)

標題: 為何算圖整個都過曝?

答案是:在你設定正確的色彩空間之前 算出來的圖很容易過曝

  • 你之前設定過的場景都是錯的.
  • 你之前算過的圖都是錯的.
  • 你以前輸入的(材質 燈光)都是錯的.
幾年前,所有的材質shader都是用錯誤的色彩空間在做計算。常見的問題包括,當使用燈光衰減 接近燈光的地方或過亮(因此有任會避免是用燈光衰減)在高光的邊界的地方出現醜陋的過亮問題,就好像2 +2 = 10的效果)

由於這一點,很多人會用某些秘技來解決此問題。方法是把高光與diffuse做單純的add混色 (像photoshop那樣),或只要diffuse強度 。

所有這些技巧是錯的,但最後的效果看啟示真實的,即使這時候的gamma=1。

可悲的是,很多人就是因為這樣反而看慣了不正確的gamma算出來的效果。

請看這兩張CG圖(一個是用Mentalray算的 另外一個是用finalrender算的)。Mentalray的效果是把tonemapper的作用法揮到極致(把過亮的部位去飽和度 增加視覺美感),而finalrender算出來的是難看的gamma=1結果。

你可能會認為finalrender的效果才是正確的 但事實並非如此。你可以看到finalrender把反射算的太亮 產生不真實的感覺。

現在的問題是,當您轉換到正確的色彩空間(finalrender或Mentalray),你輸入的圖檔是錯的 出來的結果當然也是錯的。

請看這篇關於XSI 解釋的很清楚

重點是,當你在最後套用伽瑪校正,這就表示你接下來做的每件事也要考慮到伽瑪。

顏色不會因為某些錯誤而看起來過亮。顏色之所以會看起來過量是因為你把整個環境弄的過亮....或者因為你將gamma=1的顏色顯示在gamma 2.2的螢幕所以結果反而讓顏色不會過亮!

例如 你看到所有未校正的顏色都是錯的 。他不會是最後會顯示的顏色。

貼圖也有一樣的問題,如果你有一張gamma 1.0的貼圖透過gamma 2.2的螢幕來看 但是看起來卻是正確的顏色 為何呢? 因為其實每張圖片有史以來 都會把伽瑪數值燒到圖片裡面。所以這意味著...這些圖片通通都錯了(...在這樣的歷史原因下。我們可以理解為何要把伽瑪數值燒到圖片裡面,因為這樣的圖片放到當時的CRT螢幕 反而會讓我們認為這張圖片顯示是正確的!)

是的,每一張再看到的數位相機拍出來的照片,你在網上看到,都是錯的(在以上的觀念下)。

錯。所有的圖片都錯了。

那又是為什麼這些圖看起來是正確的呢? 因為你以錯誤的gamma去算圖 然後以錯誤的gamma螢幕來觀看。因此,儘管你最終的貼圖看起來是“正確的”,但是所有的計算式 “光學的計算”過程都是錯誤的。

某些算圖軟體具有色彩校正的功能,當它讀入圖檔的時候 它會自動去gamma(un-gammaed)產生現性色彩空間的貼圖 每套算圖引擎的這類功能不太一樣 很不幸的是某些的作用不正確 某些有bug。

因此,最好的辦法是自己做顏色校正的節點轉換。

mia_exposure_simple就是這樣的節點,它是一種簡單tonemapper。 (它其實只具有亮度/對比度/伽馬控制工具 外加過亮區域的壓縮功能 避免clip現象;))

要知道,當你做了伽瑪校正後 你就會改變原本圖片的紅,綠,藍通道的權重,這就相當於改變了顏色的飽和度。
所以你一開始的時候就必須輸入正確的顏色。

過亮(Overbrights )
tonemappers的最重要工作就是要處理過亮問題。 mia_exposure_simple使用一個簡單的壓縮演算法,把顏色推到'門檻'以上,直到把它漸漸地clip成純白,否則它會直接頂到純白色變成難看的硬clip。

這個方法很重要,其實在底片,數位相機,CCD中也是這樣處理地。

用老的shader,specular highlights很容易就爆光,看起來很難看 由於hard-clipping色彩通道的關係。

這會讓調顏色的人會把顏色條的太弱(相對於真實的物理強度),因為即使是最“弱”的數值相加起來 也會很容易過曝 為什麼?因為這些顏色的加法是建立在非線性的色彩空間

請想想如果“2 +2”不等於“4”,而是“10”!

因此,如果“2 +2 = 10”,你希望效果看起來是“4”(因為你眼睛認為看起來正確),透過試誤法 你發現"2+0.5"的結果看起來像 “4”,所以原本正確應該要用2,你改用0.5 然後你就對這樣的結果滿意。

但是當你把最後的結果,放到正確的tone operator(甚至只使用老式正確伽瑪),它的結果還是會看起來像“2.5”而不是“4”。

這就是為什麼很多人會投降 說gamma真是個爛東西 我以前沒用gamma算圖都不會有這種錯誤,幹!放棄gamma!

而真正的錯誤是你的specular highlight數值太小的。

mia_material能夠正確地處理這類問題的,你會發現,如果你在用它的時候沒有使用伽瑪校正或tonemapping,你會發現最後的highlights太亮。這是因為shader本身是正確的 但是你觀看它的方式是錯的。

根據物理的算圖是很困難的,主要是因為有很多根深蒂固錯誤流程 還有軟體本身的錯誤。

很多人誤以為Maxwell是神奇的渲染器,而且遠遠優於mental ray,其實原因很簡單這類渲染器一開始的時候就是以physical rendering的流程來寫的,它並沒有陳舊的軟體包袱 與錯誤的流程要煩惱。

Maxwell可以讓所有的顏色正確顯示,然後自動修正所有輸入的圖檔,因為算圖引擎確定最終的輸出方式一定是以物理正確的色彩環境來顯示,透過physical tone mapper來與螢幕觀看!

---以下文章翻譯自http://3dlight.blogspot.com---
作者是:Andrew Weidenhammer

標題: 線性工作流程介紹(Linear Workflow Introduction)

讓我們開始談談線性色彩工作流程吧。

你可能已經知道什麼是線性工作流程,但對於那些來不懂的 以下是簡短解釋:
線性工作流程是因為你算圖器本身就是以浮點 (線性)空間來運算的。它會產生8-bit的輸出,而這個圖檔會加入gamma 為了要在螢幕上顯示。真是可惜阿。本來浮點的圖片對於後製合成是很方便的 卻在輸出的時候轉成8-bit。

如果你不了解8-bit, 與32-bit(浮點)圖片的差別,或是螢幕的gamma,那你可能要先爬文。有些好書我可以推薦你讀。The HDRI Handbook這本寫的很不錯,我高度推薦。網路上也有很多關於hdri的資料,hdri在計算機圖形學中,就是利用線性工作流程的概念。了解hdri,你就會更了解線性工作流程。

你可能認為線性工作流程有什麼大不了,因為你已經利用8-bit的方式算出好多年的美麗圖檔。其實只主要的差別,我想 可以歸結為以下:

1。物理正確性
你可以以真實的單位來創建場景,例如使用真實的燭光亮度。

2。真實光照
這說來話長,但在CG燈長久以來是以線性衰減來欺騙觀眾,或是根本就沒有衰減。這是因為燈光的線性衰減並沒有套用正確的伽瑪。這就是為什麼我們的CG前輩phong與 blinn要去研究光線是如何反應的 利用shader模擬光線效果。我們必須跨出歷史 進化到使用物理精確的材質。這就是為什麼現在有這麼多MR (architectural) shaders。它們都是針對物理精確線性流程來設計的。

3。後製的可調性大增
32位元浮點或16位元浮點有能力應付龐大的色彩和曝光調整。當你使用真實浮點的後製軟體如Fusion,大多數的濾鏡都能真實的產生效果。運動模糊效果,光暈,會表現的更真實與自然。

---以下文章翻譯自http://www.creativecrash.com 網站---
作者是 throb

你有沒有想過,為什麼你的GI算圖結果如此黑暗?那麼,事實上,其實結果不是這麼深。問題在於顯示設備(CRT或LCD)及該軟件是沒有作出調整的伽瑪是把我們的顯示圖像。這是伽瑪明確要求sRGB。技術信息sRGB可在該網站上。

讓我們看一下顯示器會如何顯示你輸入的圖檔。這是非線性顯示器。虛線是你輸入的圖檔資料 實線是螢幕根據輸入的強度所輸出的強度 因為這條實線是直線所以這個螢幕是正確地顯示。

要知道 這個螢幕校正並不是跟底片有關。事實上,這跟底片沒什麼關係。它本質上是為了要校正螢幕。

好了,現在我們來看怎樣解決這個問題。是的,這是一個問題:)嗯,朋友,我們只要再套用另外一條反向的曲線,就可以把原本的曲線變成直線了(線性化)。你看到這次實線因為我們套用的曲線而變直了。

再解釋一下,... sRGB是繪圖軟體對螢幕的校正。數位相機會對你的照片套用sRGB 但是你不會察覺這件事. 所以當你利用此照片在真正的線性工作環境中時 事實上你的操作可能會比真實世界的光線反應還要更劇烈一點。我用以下的漸層圖來說明

這是一張漸層圖 圖中是個0到1的數值 共有32階。請注意0.5數值正好在中間。這張是你輸入到螢幕的圖檔。這是一個線性圖檔!

這是你的顯示器顯示出來的樣子。在0.5的位置顯然不是在中間了。這代表螢幕是非線性的。

這是校正後的影像 沒錯 看起來比較亮了 但是這個校正讓你播放在非線性的螢幕上時 圖片顯示的是線性的 以上說明希望讀者能明白

我們再舉一個例子。

這裡有兩張圖。再中間的灰色具有0.18的數值(中間灰色點)。左邊是以sRGB編碼 右邊透過sRGB螢幕校正的影像。這會讓灰色變成.46的數值。

Gamma編碼的圖形會導致灰階的細節消失

線性圖形會保有細節
讓我們將以上觀念以3D軟體進行實戰吧:3DS Max 7.0與VRay的1.46

以上是我們算第一張的結果:

現在,我們必須將這張圖線性化,如果我們希望畫面更逼真。

首先到Customize -> Preferences -> Gamma tab 將數值改變

這樣我們才能在材質編輯器看到正確數值。

  • Brazil的用戶,你就快完成了 接下一步吧。
  • Mental Ray的用戶 到這裡算是完成了!你本來就是用線性方法在算圖。
  • Scanline render用戶-到這裡算是完成了。以後的操作都是線性流程了。

(譯者註:VRay的部份 就請直接這個網站的參考圖片 文字內容不翻譯了)

[更多文章]

6 comments:

Lien Ying Te said...

非常謝謝這麼辛苦收集資料與做這麼多解說,辛苦了~~

我是阿德。

ARKUO said...

我非常感謝你這篇文章的解析...

我的viewsonic螢幕 買來10年多了
我即使把螢幕調的亮的眼睛受不了
可是看起來還是太暗...

我一直以為是這個螢幕的瑕疵
看了你的文章後
我去找螢幕的設定
修改了gamma值

雖然是10年的螢幕了
色調十分的漂亮...

再次感謝...

.

hammerbchen said...

To 阿德, ARKUO:

感謝你們的鼓勵, 是我繼續發文的動力!

aomay said...

~U_U辛苦了....實在是不錯的文章

3DAY said...

很詳盡~~但我看不太懂(哭)...
基本上像是在MAX裡面,我需要做較正的話,應該是在gamma&lut裡面對inpuut gamma的質設定為1 output為2.2對吧?

這樣在材質編輯的時候為gamma為1的圖加個gamma&gain的shader(gamma為2.2)就可以進行較正了吧!?

還是說gamma&lut設定裡面都設為2.2
gamma為1的材質都不用做設定就能輸出顯示成2.2?

感謝你的文章

hammerbchen said...

to 3DAY:

因為各家渲染器的設定方式會有點不同 例如
http://vray.info/tutorials/vraydaylight/

這篇你可以參考他的Vray設定, 不過如果是MR的話, Output Gamma要改為2.2