Tone mapping进化论

Tone mapping进化论
https://zhuanlan.zhihu.com/p/21983679?refer=highwaytographics

Reinhard tone mapping非常简单,用代码描述就三行。

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

粗暴派

到了2007年,孤岛危机(Crysis)的CryEngine 2,为了克服Reinhard灰暗的缺点,开始用了另一个tone mapping的方法。前面提到了tone mapping就是个S曲线,那么既然你要S曲线,我就搞出一个S曲线。这个方法更简单,只要一行,而且没有magic number。用一个exp来模拟S曲线。

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

CE的曲线中间的区域更偏向于小的方向,这部分曲线也更陡。

拟合派

到了2010年,Uncharted 2公开了它的tone mapping方法,称为Filmic tone mapping。当年我也写过一篇博客讲KlayGE切换到Filmic tone mapping的事情。这个方法的本质是把原图和让艺术家用专业照相软件模拟胶片的感觉,人肉tone mapping后的结果去做曲线拟合,得到一个高次曲线的表达式。这样的表达式应用到渲染结果后,就能在很大程度上自动接近人工调整的结果。

最后出来的曲线是这样的。总的来说也是S型,但增长的区域很长。

那么这条路径有多小呢?只要几行,系数来自于Krzysztof Narkowicz的博客文章。

float3 ACESToneMapping(float3 color, float adapted_lum)
{
    const float A = 2.51f;
    const float B = 0.03f;
    const float C = 2.43f;
    const float D = 0.59f;
    const float E = 0.14f;

    color *= adapted_lum;
    return (color * (A * color + B)) / (color * (C * color + D) + E);
}

看着很像Uncharted 2的做法吧,都是多项式拟合。但是式子比Uncharted的简单,并不需要算两个多项式并相除,只要算一个,一次搞定。它的曲线是这样的。

可以看出来,比之前的任何一个都要鲜艳,并且没有因此丢掉细节!当之无愧成为目前最好的tone mapping算法。

更好的地方是,按照前面说的,ACES为的是解决所有设备之间的颜色空间转换问题。所以这个tone mapper不但可以用于HDR到LDR的转换,还可以用于从一个HDR转到另一个HDR。也就是从根本上解决了VDR的问题。这个函数的输出是线性空间的,所以要接到LDR的设备,只要做一次sRGB校正。要接到HDR10的设备,只要做一次Rec 2020颜色矩阵乘法。Tone mapping部分是通用的,这也是比之前几个算法都好的地方。

目前一些新的游戏,比如Rise of the Tomb Raider、UE 4.8,也都切换到ACES的tone mapping曲线。

猜你喜欢

转载自blog.csdn.net/kuangben2000/article/details/70199275