ToneMapping算法簡介


說起Tone Mapping,就不能不提HDR。HDR(High Dynamic Range, 高動態范圍)是一種顏色范圍,在傳統的RGB中,每一個通道的顏色都是從屬於[0,1]之間的浮點數范圍,0代表純黑,1代表純白,超過了1仍然會歸為白色;但是在現實光照方程中卻沒有這個限制,光的強度可以設置為任意大,那么就需要重新設定顏色的范圍,這就是HDR。有了HDR,場景中亮的東西可以變得非常亮,暗的東西可以變得非常暗,而且充滿細節。
之前提過的顏色值只能屬於[0,1]之間的算法稱作LDR(Low Dynamic Range,低動態范圍),那么假設我們在計算中采用的是HDR,因為計算機屏幕只能顯示[0,1]之間(也就是LDR)的顏色,因此在最終輸出顏色的時候需要做一個從HDR到LDR的轉換,具體的轉換算法就是ToneMapping。
《LearnOpenGL》中提到了兩種ToneMapping的算法,我們對此分別進行說明。
最簡單的色調映射算法是Reinhard ToneMapping。它的實現非常簡單,代碼如下:

float3 ReinhardToneMapping(float3 color, float adapted_lum) 
{
    const float MIDDLE_GREY = 1;
    color *= MIDDLE_GREY / adapted_lum;
    return color / (1.0f + color);
}

MIDDLE_GREY是默認為灰的顏色,adapted_lum是統計的亮度(具體的計算可以參考Photographic Tone Reproduction for Digital Images這篇論文),我試了一下,它的函數圖形如下(默認MIDDLE_GREY和adapted_lum都是1):

雖然它的做法簡單粗暴,亮的變暗,暗的變亮,但是缺點就是把所有的顏色都往中間壓縮,整體畫面會顯得灰暗,下圖來自於使用該算法的一個場景:

后來CryEngine又提出了另一種ToneMapping方法,將亮的部分壓平:

float3 CEToneMapping(float3 color, float adapted_lum) 
{
    return 1 - exp(-adapted_lum * color);
}

其中adapted_lum是曝光度,曝光度越高整體越亮,比Reinhard的方法更鮮艷,如下圖所示:

以上就介紹這兩種方法,后來人們還提出了更多效果更好的方法,可以參照這篇文章進一步地學習:https://zhuanlan.zhihu.com/p/21983679


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM