本篇参考B站视频 “技术美术百人计划”·霜狼_may ;
《Shader入门精要》·冯乐乐女神著;
https://www.cnblogs.com/wickedpriest/p/13048588.html
ToneMaping https://zhuanlan.zhihu.com/p/21983679
Lut https://www.btbat.com/2943.html
深入理解 PBR/基于图像照明 (IBL)https://zhuanlan.zhihu.com/p/66518450
本篇主要用于自我复习,如有疑问或发现有什么错误,请多指教~
在上一篇中有简单介绍HDR,这一篇展开来说下,主要包括HDR/LDR以及IBL相关;
1.动态范围
Dynamic Range,简而言之,它指的是最高与最低亮度值间的比值。
现实中,场景的最亮和最暗范围非常大,超出显示器能显示范围256阶灰阶(单通道精度8位,灰度为2的8次方)。
2.HDR
High Dynamic Range,高动态范围;
3.LDR
Low Dynamic Range,低动态范围
不同显示器由于厂家和制作手法不一,其物理亮度并非统一,而LDR的范围是0-1,对应在不同屏幕上匹配对应屏幕的最低0与最高1;
4.Tone Maping
自然界中的亮度范围差异十分明显,萤火之光与太阳光对比,差异极为明显,为了将其从高动态范围转换到显示器上可以显示的低动态范围的过程(HDR->LDR)即为Tone Mapping(色调映射);
关于Tone Maping的算法简单举例四种,不同点其实都是在于S曲线算法的生成,具体参考这篇文章
float3 ReinhardToneMapping(float3 color, float adapted_lum)
{
const float MIDDLE_GREY = 1;
color *= MIDDLE_GREY / adapted_lum;
return color / (1.0f + color);
}
float3 CEToneMapping(float3 color, float adapted_lum)
{
return 1 - exp(-adapted_lum * color);
}
float3 F(float3 x)
{
const float A = 0.22f;
const float B = 0.30f;
const float C = 0.10f;
const float D = 0.20f;
const float E = 0.01f;
const float F = 0.30f;
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}
float3 Uncharted2ToneMapping(float3 color, float adapted_lum)
{
const float WHITE = 11.2f;
return F(1.6f * adapted_lum * color) / F(WHITE);
}
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);
}
视频中提到,在拍照时,将曝光值进行计算,映射为相机能感受的范围内,这一阶段受光圈,快门等组件影响;
然后将该值输出为一个线性值存到相机中,经Lut变换(Look up table用于调色也可称滤镜),通过白平衡,色彩映射,Gamma校正等一系列过程,将其结果烘焙为Lut;
关于Lut相关可以参考
Trick:通过在PS里做出一张Lut导出后,在引擎里再采样调整画面;
1.为何需要HDR
2.Unity中设置HDR
Camera-HDR设置
开启后场景将渲染为HDR图像缓冲区,再进行屏幕后处理,Tonemapping中将HDR转化为LDR,然后将LDR图像发送给显示器;(经测试 默认情况下几乎没啥影响,当使用post volume后调整数值后会产生一定影响)
Lightmap HDR设置
选择High Quality启用HDR光照贴图支持,Normal Quality切换为使用RGBM编码;
(RGBM编码:颜色存储到RGB通道中,乘数(M)存储到Alpha中)
设置成功后会增加Intensity滑动条调整颜色强度,每增加1,光量增加一倍;
3.HDR优缺点
4.HDR与Bloom
Bloom用于表现溢光效果,其原理如图
使用的代码参考《入门精要》的Bloom对应章节,下面是对应的每帧变换和对应步骤
1.IBL是啥
IBL(Image Based Lighting)也就是基于图像的光照。相当于一个无限大的球面光源在照射场景。辐射度由 environment map 决定。
(接下来的是半糊状态自我参悟,不保证准确性,如有需要请直接参考链接https://zhuanlan.zhihu.com/p/66518450)
2.我们知道一个完整的光照模型需包含漫反射与镜面反射部分,而在其中又可以根据光源分为直射光部分和环境光部分,通过使用IBL,我们可以从中采样获取一个irradiance map作为环境漫反射光,具体步骤参考该篇对IBL的解析,unity中我们可以在图片格式中修改(经尝试后发现好像区别不大?)
3.既然有对应环境漫反射部分,自然有对应环境镜面反射的部分,从中提取的cubemap被称为pre-filter environment map,根据粗糙度不同表现效果不同,感觉有点类似调整Mipmap的感觉;unity中图片设置里也有高光反射部分
4.合成最后输出
关于最后输出部分参考上面说的文章,这里单独拎出来上面讲到的获得的两张图的处理;
5.关于尝试
拿了一张HDR图在PS里修改成LDR(输出后,将两者都用texCUBElod方式进行采样,图片格式设置如下
关于在PS里HDR修改为LDR,修改时在PS里调整HDR色调,在庄懂的课里有讲过,前面的实践篇中也有对应操作
然后调整Mipmap层级后,对比如gif图: