LearnOpenGL Gamma校正

本篇文章是基于LearnOpenGL的总结

Gamma 校正

物理亮度是基于光子数量的, 一般是线性的, 而传统的CRT显示器, 会将亮度做2.2次幂. 即会将中间的笔直的直线, 映射成为下方弯曲的直线.
可以计算下[0, 1]内的数取2.2次幂的结果, 接近0的数 0. 2 2.2 < 0.2   = 0.02 0.2^{2.2} < 0.2 ~= 0.02 0.22.2<0.2 =0.02 0. 8 2.2   = 0.61 0.8^{2.2} ~= 0.61 0.82.2 =0.61
在这里插入图片描述
所以我们如果将0.5的亮度在物理中提量1倍, 到1.0, 而在显示器上实际呈现的效果将会是从0.218 提高到 1, 增幅达到4.5倍, 显然是不科学的.
因此需要Gamma校正, 先对我们的亮度取 1 2.2 \frac{1}{2.2} 2.21次幂, 比如
( 0. 5 1 2.2 ) 2.2 (0.5^{\frac{1}{2.2}} )^{2.2} (0.52.21)2.2 就会变回到线性空间了.
但是要注意Gamma校正一定要放在最后一步, 如果放在fragment shader之间做Gamma校正, 那么后面取的颜色都是在校正后的非线性空间上, 会出问题.

sRGB纹理

sRGB空间定义的gamma接近于2.2, 因此相当于gamma空间
当我们在sRGB空间去制作图片, 并且在sRGB中观看图片, 没什么问题.
但是如果我们是将纹理放置到线性空间(上图中笔直的线的空间), 那么会有问题, 因为我们输出到显示器上的时候, 会自动进行Gamma校正, 会使得颜色在上边的曲线上, 这样颜色就会过曝.

在这里插入图片描述
解决方法, 校正回来, 对 颜 色 1 g a m m a 颜色^{\frac{1}{gamma}} gamma1校正回来.

衰减

光的衰减物理上与距离平方成反比

float attenuation  = 1.0 / (distance * distance)

然而这样的衰减在实际屏幕上, 造成衰减效果过于剧烈, 光只能照亮一小部分区域,
另一种方式使用以下双曲线函数

float attenuation = 1.0 / distance

双曲线函数比二次函数 不用gamma校正更真实, 因为在屏幕的gamma次数下
双曲函数衰减会变成如下形式
( 1.0 / d i s t a n c e ) 2.2 ∼ ( 1.0 / d i s c a n t e ) 2 (1.0 / distance)^{2.2} \sim (1.0 / discante)^2 (1.0/distance)2.2(1.0/discante)2, 在屏幕gamma次数下, 更接近物理模型.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值