從真實世界到渲染
問題
在PBR的渲染方程中,最常見的一個就是 ,雖然看起來含義很直觀,但是仔細一想就會想到很多問題,這些量的單位究竟是什麼?進一步思考,顯示器是如何模擬現實世界的顏色的?HDR究竟是啥?帶著這些問題,我們開始來閱讀本篇文章.
輻射量
輻射量是使用純物理的方式來描述電磁波和輻射.簡要介紹常用的輻射量.
1.輻射能(energy) ,單位是焦耳 ,單個光子的輻射能表示為 .
2.輻通量(flux) ,單位時間內發射,接收或傳輸的能量 ,單位是瓦特 .
3.輻照度(irradiance) /輻出度(radiant exitance) ,輻照度表示單位面積受到的輻通量 ,輻出度表示單位面積發出的輻通量 ,單位都是 .輻通量為 的點光源在距離 處球面上的輻照度為 .
4.輻強度(radiant intensity) ,元立體角內的輻通量 ,單位是 .
立體角
立體角(solid angle)可以看作平面角在球體上的擴充套件,單位是球面度 .整個球面的總立體角是 ,半球面的總立體角和是 .
5.輻亮度(radiance) ,表示單位面積和單位立體角上的輻通量, ,單位是 .輻亮度是用來描述感測器(攝影機,人眼等)感受輻射最常用的量,也是最重要的量.
輻亮度定義
光度學
輻照學的量都是用純物理的方式來描述,然而其實人眼只能看到波長在400nm-700nm波長的電磁波,所以需要單獨用來描述人眼感知的光學量.
光度學中的量其實是跟輻照學中的量是一一對應的,這裡不再逐個說明.包括光通量 (單位流明 ),光照度 (單位勒克斯 ),發光強度 (單位坎德拉 ),光亮度 (單位 ).
對應關係
其中發光強度是光學的基本量,是國際單位制七個基本單位之一.
一些常見表面的亮度值:
常見光亮度
輻射量和光學量的轉換
光在不同波長上的分佈,叫做光譜功率分佈(spectral power distributions/SPD).
三個不同的SPD,第一個是單色光,第二個是混合光,第三個是戶外自然光
人眼作為一種探測器,輸入是輻射量表示的可見光輻射,輸出感受值的光學量.輻射能到發光能的轉換可以表示為 .
是光譜功率分佈,單位是 ;
是光度函式,沒有單位;
是波長,單位是 .
光度函式
渲染公式
我們在所有的渲染公式中用到的都是光度學單位(因此本文後面說講的單位都是光度學單位,不再用下標區分).而描述我們看到的顏色的最終結果的單位都是 .
鑑於點光源和平行光源的不同特性,在遊戲引擎中其實是使用不同的單位來描述其強度,點光源用發光強度 ,單位是 ,平行光源是用光照度 ,單位是 .
對於點光源 ,發光強度為 ,對於距離 處的形成的光照度為 .可見點光源在某處的光照度和距離平方成反比.
這樣,我們再看反射方程,就清楚地理解其中的含義了:
物體表面的出射亮度等於所有入射光在在半球表面反射後的積分.
單位是 , 單位是 .
CIE標準色度學系統
雖然自然界真實的光照有很複雜的SPD,但是因為人眼的顏色感受細胞其實只有三種,分別感受紅綠藍三種顏色.所以其實可以將複雜的光譜功率分佈轉換成RGB表示.
根據CIE-RGB標準,指定三原色 (645nm), (526nm), (444nm),用下面的光譜對映函式和SPD求內積,來將一個任意的SPD表示為三個刺激值.
RGB
但是這種方式得到的值有負數,不便於計算,因此又有了CIE-XYZ系統,在CIE-RGB的基礎上改進.
將SPD 通過求內積轉換成三個數字 三刺激值:
XYZ
值得注意的是 的曲線其實就是前面講過用來計算光度學量的光度函式,即 值可以作為顏色的亮度值.
為了把顏色的亮度和色度區分開,再定義
把 值忽略,用 的值來做出一張圖,得到CIE色品圖(hromaticity diagram).
圖中的邊緣的曲線表示純色.圖中黑色的點是白點,代表D65純白色.在圖中任取一顏色,連線白點和顏色點延長後和邊緣相交處的顏色叫做色相(hue),白點到顏色點的距離與白點到邊緣的距離的比值叫飽和度(saturation).
CIE1931色品圖,圖中的白色三角形表示sRGB的色域,黑色的點表示D65白點
從色品圖中取色,再加上亮度值,就可以構成 座標系統來描述任意顏色.
在色品圖中選取三點作為純色RGB顏色,構成一個三角形,就組成一個色域(gamunt).色域中的顏色可以任意進行線性混合.上圖中的白色三角形就是電視和顯示器中最常用的sRGB的色域.需要注意的是,色相圖中的色域只是一個投影,真實的色域應該是一個立體形的,包括亮度值.
為了使顏色在色品圖中分佈更加均勻,在CIE 1931 XYZ色品圖的基礎上又推出了CIE 1976 UCS色品圖.
CIE1976 UCS色品圖,以及三個不同的色域
RGB色域有很多種,上圖是常見的三種.sRGB(這裡指的是線性sRGB)是顯示器中最常見的色域,也是目前絕大部分實時渲染中用到的色域. REC 709和sRGB白點相同,常用於高清電視.一些用來做照片剪輯的顯示器使用Adobe 1998色域. DCI-P3是蘋果系列產品使用的色域. ACEScg是一種設計用來計算渲染的色域.
從RGB色域到 三刺激值的互相轉換也非常簡單,其實就是一些線性的運算,可以用兩個3X3矩陣來表示.
比如在sRGB色域中,得到[ .上面說過 值其實就是亮度值,所以這也是實時渲染中常用來計算亮度來進行自動曝光的一個公式.
儘管從嚴格意義上來說RGB顏色並不能完全反映真實世界中物體對光SPD的反饋,但是在絕大多數情況下效果都是非常不錯的.目前只有少部分工業級電影的離線渲染使用頻譜渲染.
下面就來講講顯示器的顯示.
伽馬校正
早期的CRT顯示器,輸入的電壓和顯示的亮度並不是線性關係,而是大概是 的關係.現代的液晶顯示器基本沿襲了CRT顯示器的輸入輸出關係.液晶顯示器的顯示亮度和輸入值的關係也稱為EOTF(electrical optical transfer function),由硬體來實現,在電視,顯示器,電影等不同的場合亦有不同的標準.
實時渲染中的顏色計算都是線上性空間中進行的,因此要想讓顯示器輸出正確的顏色值,需要在最後一步輸出到FrameBuffer時進行伽馬校正,來抵消EOTF的效果.
伽馬校正
sRGB編碼
人眼可以識別很大範圍亮度的光照,這也導致了人眼對亮度的感受會隨著亮度的增高而減弱.比如下面圖中的線性編碼的亮度,會明顯覺得人眼對低亮度時的變化更加敏感.
線性編碼和伽馬校正編碼
假設我們用8bit(0~255)來編碼顏色,如果線性地按照亮度的關係進行編碼,就會導致人眼在低亮度時感覺相鄰顏色變化很大,而在高亮度時感覺相鄰顏色變化很小,導致編碼空間的浪費.
所以我們將線性的sRGB色域顏色值先應用一次伽馬校正,組成sRGB伽馬編碼.這樣即可以完美利用編碼空間,又不需要在顯示時再進行伽馬校正,可謂是一舉兩得.
平常我們見到的大部分各種格式的圖片,都是按照sRGB伽馬來進行編碼的.
sRGB與渲染
為了保證渲染結果計算正確,在計算的時候需要採用線性的顏色值.所以在從圖片中取畫素值的時候,需要先將伽馬校正後的畫素值解碼回來成線性的顏色,渲染計算完後,再伽馬校正輸出到framebuffer.
sRGB渲染
如果忽略伽馬校正,就會導致顏色計算失真,也會對AA有影響.
有的手機出於效能考慮,會使用 來加速伽馬校正,也有的會完全忽略伽馬校正.
HDR(high dynamic range)顯示器
先說明下HDR一般有兩種意思,這裡的HDR和SDR(standard dynamic range)對應,指的是HDR顯示器.而在渲染中所說的HDR,其實是指tone mapping,後面會講到.
隨著現代顯示器不斷升級,可以支援的更大的色域,支援的最大亮度也更高.HDR顯示器使用Rec. 2020和Rec. 2100標準.Rec.2020 定義了一個比sRGB大得多的色域,Rec. 2100定義了PQ和HLG兩種非線性編碼.
從應用向顯示器傳輸HDR資料的時候,有HDR10,scRGB,Dolby Vision三種方式.
Tone Mapping
現代的PBR渲染中,在計算渲染和光照時,都是按照真實世界的光亮度來計算.計算完成後還需要把亮度值轉換成可以在顯示器中顯示的範圍,這個過程就叫做tone mapping.可以說, tone mapping在繪畫,攝影,電影等領域早已得到廣泛地應用.
渲染中所說的HDR,和LDR相對應,tone mapping就是把HDR範圍的光亮度轉化成顯示器可以顯示的LDR光亮度.
現實世界中和人眼可以識別的光亮度範圍要比顯示器的亮度範圍要大得多,tone mapping的目的,就是儘可能還原影像中的細節,而不是單純地線性對光亮度進行縮放.所以tone mapping實現的光亮度對映,是一條S型的曲線,這樣可以保留亮部和暗部的細節.
比如最早期的Reinhard tone mapping,實現非常簡單.顏色的對映關係是這樣的: , 表示影像的平均亮度.
Reinhard tone mapping
後來出現了各種各樣的tone mapping方式,對Reinhard tone mapping進行改進.
ACES是美國電影藝術與科學學會提出的一種用來在電影中使用的一整套的編碼顯示方案.實時渲染中借用了其中tone mapping的部分,目前已成為遊戲引擎中的主流方案.
如果輸出的目標是HDR顯示器,因為顯示器的最高亮度往往較高,且有的顯示方式自帶tone mapping,所以需要根據具體的顯示方案做出調整.
曝光度和EV100
不管以何種方式進行tone mapping,計算影像的整體平均亮度都是必須的.計算影像的整體亮度一般採用log平均的方式.
傳統的方式是算出影像的亮度log值後,不斷DownSample直到一個1x1的texture,即可算出影像的平均亮度. 現代的做法是使用ComputerShader,統計每個亮度範圍的畫素點數,再綜合計算得到一個亮度值.
EV(exposure value)在攝影中表示需要的曝光值.EV100表示在ISO100標準下的EV值,和光亮值的關係可以用公式表示為 , 表示光在光學系統中傳遞時的損耗,遊戲引擎中是一個模擬值,常取 .在遊戲引擎中也常用EV100的值來定量地描述曝光值。
參考連結
https://learnopengl.com/Advanced-Lighting/Gamma-Correction
https://zhuanlan.zhihu.com/p/37800433
https://en.wikipedia.org/wiki/Luminosity_function
https://en.wikipedia.org/wiki/Chromaticity
https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
https://zhuanlan.zhihu.com/p/21983679
https://zh.wikipedia.org/wiki/%E6%9B%9D%E5%85%89%E5%80%BC
<Real Time Rendering 4th>
<工程光學 鬱道銀>
作者:TC130
專欄地址:https://zhuanlan.zhihu.com/p/118272193
相關文章
- AndroidOpenCV(四十六):非真實渲染AndroidOpenCV
- Android MVP架構從入門到精通-真槍實彈AndroidMVP架構
- 真實感皮膚渲染技術總結
- 讓遊戲世界更加真實可信遊戲
- 瀏覽器從輸入URL到渲染瀏覽器
- 真實世界中 Rust 程式的安全實踐Rust
- 網頁渲染方式-從靜態頁面到服務端渲染網頁服務端
- 剖析Unreal Engine超真實人類的渲染技術Part 2 - 眼球渲染Unreal
- Vue 服務端渲染(SSR)、Nuxt.js – 從入門到實踐Vue服務端UXJS
- Vue 服務端渲染(SSR)、Nuxt.js - 從入門到實踐Vue服務端UXJS
- Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐Vue服務端UX
- Vue.js從Virtual DOM對映到真實DOM的過程Vue.js
- 從輸入URL到渲染的完整過程
- React 服務端渲染從入門到精通React服務端
- 樹人:從《魔戒》到《魔獸世界》
- GPU精粹與Shader程式設計(四):真實感渲染GPU程式設計
- 晶片科技:從微觀世界到現實應用的奇妙之旅晶片
- 從 Flutter 的視訊渲染到 App 落地經驗FlutterAPP
- 剖析Unreal Engine超真實人類的渲染技術Part 3 - 毛髮渲染及其它Unreal
- 世界先得真實,開放地圖才有意義地圖
- Vue檢視渲染原理解析,從構建VNode到生成真實節點樹Vue
- React從零實現-元件渲染和setStateReact元件
- Linux從頭學08:Linux 是如何保護核心程式碼的?【從真實模式到保護模式】Linux模式
- 從後端到前端之Vue(三)小結以及一顆真實的大樹後端前端Vue
- 真實世界的人工智慧應用落地——OpenAI篇 ⛵人工智慧OpenAI
- “真實”與“好玩”的武俠世界是如何打造的?
- React從零實現-節點建立和渲染React
- 服務端渲染到前端渲染,再到“服務端渲染”服務端前端
- 機器學習的7個真實世界生產案例機器學習
- 視覺化,帶你走進“真實”的虛擬世界視覺化虛擬世界
- PHP 7:真實世界的應用開發(中文翻譯)PHP
- 雲棲科技評論|“虛擬X”佔領真實世界
- 為什麼應該切換到實時渲染
- 當電子遊戲的主題“過於真實”:從“娛樂”到“嚴肅”的跨度遊戲
- 爬蟲實戰:從外地天氣到美食推薦,探索乾飯人的世界爬蟲
- 中國5強:從世界級城市到世界級城市群(附下載)
- 走進JavaWeb技術世界10:從JavaBean講到SpringJavaWebBeanSpring
- 從繁華現代都市到狂野西部世界——R星