零基础学习OpenGL(十一)--Gamma校正

      人眼对光的敏感度在不同亮度上是不一样的,人眼会对暗的区域变化更加敏感。如果用8位空间来存储像素,0-1区间可以表示256种亮度,但是我们不会一半表示暗的,一半表示亮的(即暗和亮都是128种颜色)。因为我们应该花更多的空间去存储暗的区域,换句话说,暗的需要被区分成更多种。

       编码:当摄影设备储存照片时对像素进行编码,如果使用0.45的编码伽马对输入的亮度进行编码,那么0.5像素对应的亮度不是0.5,可能是0.22,因为 0.5 约等于 0.22的 0.45次方。  伽马曲线:输出 = 输入的gamma次方。

       解码:图片放在显示器里显示的时候,我们需要解码,使得输出的亮度和捕捉到的亮度一样,是线性的。每种显示设备都有自己的Gamma值。设备输出亮度 = 电压的Gamma次幂。Gamma等于1是一种理想的线性状态。过去,多数监视器是阴极射线管显示器(CRT)。这些监视器有一个物理特性就是两倍的输入电压产生的不是两倍的亮度。产生约为输入电压的2.2次幂的亮度,这叫做监视器Gamma。非常巧合,不需要任何调整,CRT显示器补偿了图像捕捉设备的伽马曲线。

        Unity默认的空间是伽马空间,伽马空间下渲染会导致很多非线性空间下的计算,如果要把伽马空间转换到线性空间,就需要伽马校正。如果直接输出渲染而不进行任何处理,在经过显示器的显示伽马处理后,会导致图像整体偏暗。Gamma校正(Gamma Correction)的思路是在最终的颜色输出上应用监视器Gamma的倒数。回头看前面的Gamma曲线图,你会有一个短划线,它是监视器Gamma曲线的翻转曲线。我们在颜色显示到监视器的时候把每个颜色输出都加上这个翻转的Gamma曲线,这样应用了监视器Gamma以后最终的颜色将会变为线性的。

       有两种在你的场景中应用gamma校正的方式:

       一、使用OpenGL内建的sRGB帧缓冲。 自己在像素着色器中进行gamma校正。 第一个选项也许是最简单的方式,但是我们也会丧失一些控制权。开启GL_FRAMEBUFFER_SRGB,可以告诉OpenGL每个后续的绘制命令里,在颜色储存到颜色缓冲之前先校正sRGB颜色。sRGB这个颜色空间大致对应于gamma2.2,它也是家用设备的一个标准。开启GL_FRAMEBUFFER_SRGB以后,每次像素着色器运行后续帧缓冲,OpenGL将自动执行gamma校正,包括默认帧缓冲。gamma校正将把线性颜色空间转变为非线性空间,所以在最后一步进行gamma校正是极其重要的。

        二、我们在每个相关像素着色器运行的最后应用gamma校正,所以在发送到帧缓冲前,颜色就被校正了。

        fragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));

参考自https://learnopengl-cn.github.io

猜你喜欢

转载自blog.csdn.net/jfy307596479/article/details/84749243
今日推荐