Li Jiaheng's blog
1238 字
6 分钟
LearnOpenGL·二·光照·Gamma矫正、HDR、Bloom泛光
2024-04-23

这是对learnopengl的简单笔记。原教程网址:learnopengl。原教程同时涉及图形学的基本理论与opengl API,本文更多关注API,而简化甚至省略了背后的图形学原理性内容。

Gamma矫正#

这是一种相当简单的技巧,但是能很显著的提高真实性。
我们所有计算是基于“物理”的(当然不是真的物理,只是希望更可能近似),我们算出来的颜色,算出来的结果,1就应该是1个单位的光强,0.4就应该是0.4的光强。我们希望显示屏如实 地展示出我们算出来的颜色,但是并不能。
我们计算的值确实能完全控制硬件“发光”,1就射出1单位的光,0.5就射出0.5的光,这个确实是线性的。但光通过屏幕显示出来,就不是了:一般而言,显示屏显示的光亮和它背后发出来的真实光亮有一个幂函数的关系,也就是所谓的Gamma!
L显示屏=L计算γL_{显示屏} = L_{计算}^\gamma
一般情况下,这个Gamma是2.2,这几乎是一条行业规矩了。

上述所说,我们计算的结果、我们希望他如我们计算结果那般完全相等的显示的,可以称作“线性空间”(只是个名字,不是数学上的那个)。

也就是,我们眼睛之间看到的,其实是计算出来的颜色值的Gamma次幂!因为颜色是0~1的,所以人眼最后看到的色值偏小(不加Gamma矫正)。
而我们希望我们算出来这个颜色、在人眼看到也是这个颜色,所以需要进行Gamma矫正,很简单,只要在把数据传到屏幕上之前,先 ^1/Gamma就行了,这就是所谓Gamma矫正。
L=L物理1γL = L_{物理}^{\frac{1}{\gamma}}
然后这个L传入屏幕,最终显示出来的颜色就对了。

具体做法是,在片段着色器的最后,

void main()  
{  
    // do super fancy lighting  
    [...]  
    // apply gamma correction  
    float gamma = 2.2;  
    fragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));  
}  
NOTE

对于Gamma矫正的解释,还有从人眼对不同亮度级的感知能力的角度来说。人眼对亮度值的敏感度不是线性的,而是先抖、后平的曲线,人眼对低亮度的变化更敏感。Gamma矫正的效果是一个幂小于1的幂函数,由于亮度(“定义域”)恰在0-1,这个幂函数其实就是人眼对亮度敏感度的简单模型,让结果更契合人眼。
也就是说,并非显示屏显示出来的不是线性亮度级,而是人眼对亮度级的感知不是线性的,所以我们要把线性亮度级变换为符合人眼的幂律关系。

SRGB空间#

一般设计师设计贴图等,看到的颜色直接是屏幕上显示的颜色,而最终保存的成果,是导致屏幕显示出设计师想要的颜色的那个“真实”颜色值——可以理解为,这个保存下来的值天然已经进行过Gamma矫正,如果再进行Gamma矫正、让屏幕忠实地显示出所保存纹理图案的真实色彩,反而失真了(因为设计师在设计的时候就是在失真的条件下设计的,他看到失真的效果是他想要的,那我们就不能修正这个失真)。

而这种天然经过Gamma矫正、我们不希望对他们进行Gamma矫正的,就是SRGB空间。大部分设计工作,都是在SRGB空间上进行的(设计师直接看屏幕的显示)。对于这些不需要Gamma矫正的纹理(大部分纹理图案等都是SRGB空间),OpenGL提供了硬件支持:

glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);  

注意那个GL_SRGB参数。它相当于先把纹理色值转换到线性空间去了(就是认为的进行Gamma次幂计算,让颜色值真的变成设计师所看到的颜色值了)。然后就不用管他了,直接当成普通纹理用。

注意指定SRGB需要十分谨慎,一般指定颜色的贴图(如漫反射贴图等)都是SRGB,而和物理相关的,如法线贴图、置换贴图等,都是线性空间——但因为这些东西不是颜色,所以自然不应该Gamma矫正。

HDR#

先咕着。

Bloom#

总体原理时,先渲染一张图,然后选择这张图中的亮出(亮度大于某个阈值的像素),剔除掉不够亮的,这样就剩下够亮、要产生泛光的部分,然后使用金字塔降采样、升采样,让这部分模糊出去、“泛”出去,然后叠加回原图,营造泛光效果。

咕咕。

LearnOpenGL·二·光照·Gamma矫正、HDR、Bloom泛光
https://namisntimpot.github.io/posts/cg/opengl/二光照gamma矫正hdrbloom泛光/
作者
Li Jiaheng
发布于
2024-04-23
许可协议
CC BY-NC-SA 4.0