OpenGL中的Gamma校正篇

Gamma矫正

标签(空格分隔): OpenGL


Gamma

灰度系数,每种显示设备都有自己的gamma值,理想状态的gamma值是1。但是一般都不会是1。

  • 大于1,显示出来的画面会比理想的画面暗。
  • 小于1,显示出来的画面会比理想的画面亮。

灰阶
在这里插入图片描述

第一行是人眼感知的正常灰阶,是非线性亮度。第二行是物理世界的物理亮度,物理亮度是线性亮度。通过监视器,会将物理亮度映射到人眼的正常灰阶。
在我们通过显示来配置颜色和亮度的时候,我们是基于显示的颜色和亮度来调节的,我们调节的是物理亮度,在线性的情况下是正确的效果,但是在显示上显示出来的画面就会比我们预想的要暗一点。所以在计算亮度的时候就需要考虑到非线性上面的变化计算亮度,否则达不到我们预想的效果。
在这里插入图片描述

Gamma校正

原理:在颜色发送给监视器之前,先对其进行处理,也就是颜色的1/Gamma次方,在监视器内,会对颜色进行二次处理:(1/Gamma)*Gamma,这样就能在监视器处理之后输出线性的灰阶,在亮度调节时候,就不需要进行另外的计算。
两种校正方法:

  • 使用OpenGL内建的sRGB帧缓冲,每次像素着色器运行后续帧缓冲,将自动进行校正。
glEnable(GL_FRAMEBUFFER_SRGB);
  • 自己在需要校正的地方写代码进行校正。
float gamma=2.2;
fragColor.rgb=pow(fragColor.rgb,vec3(1.0/gamma));

sRGB纹理

sGRB纹理编辑者在编辑时候是在sRGB空间中创建的,在使用时就会发生二次校正的情况,在我们基于监视器上看到图像的时候,就进行了一次校正,在我们渲染的时候我们又进行了一次校正,这样的情况下,画面会比预期的画面要亮。
两个方法:

  • 重校,在纹理校正的时候对其进行相反的操作,返回到原本的状态。
float gamma = 2.2;
vec3 diffuseColor = pow(texture(diffuse, texCoords).rgb, vec3(gamma));
  • 将sRGB纹理定义为sRGB纹理,OpenGL将会对其进行操作。specular贴图和法线贴图基本是在线性空间下的,所以不能定义成sRGB纹理。
 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

衰减

线性衰减公式:
float attenuation = 1.0 / (distance * distance);
双曲线衰减公式:
float attenuation = 1.0 / distance;

对于非线性的亮度使用双曲线衰减公式,对于线性的亮度也就是物理亮度时候使用线性衰减公式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值