再谈gamma校正——重要知识点

什么是gamma校正,经过一番学习之后,我想用最简单的百余字说明这个问题。
这里首先给出几个参考网址:
https://blog.csdn.net/candycat1992/article/details/46228771/
https://www.bilibili.com/video/BV15t411Y7cf?from=search&seid=4640175940751520217
https://zhuanlan.zhihu.com/p/66558476
https://blog.csdn.net/yangxuan0261/article/details/92732725
https://zhuanlan.zhihu.com/p/36507196
https://zhuanlan.zhihu.com/p/66558476

就给这几个吧,多了看的是一头雾水,不知所云,但是我今天将会以全新的角度去解释这个问题,希望是正确的解释哈,不对的话,请轻捶。。。

我举个例子:
首先,回顾下泰塔尼克这部电影,在杰克和肉丝谈情说爱的high点时,崩的一声,来了个撞冰山。
铁达尼克从此成为了my heart will go on and on …
ok,到这里我们不要忘记,本文谈论的啥,是gamma校正。

当船快沉的时候,即需要抢座位。
加入我们只有100个座位。
考虑儿童、女士优先的原则,只能选择100个人坐进去,逃生。
那么轮船上那么多人,假设有10000个,此时只能选择100个。这就涉及到取舍问题,who die, who live?
显然那些重要的人,优先得到拯救。

回到gamma校正,涉及到四个步骤:
自然界的颜色-》相机采集(存储成图片)-》显示器显示-》人眼看到自然界颜色

自然界的颜色无数——》对应泰坦尼克的遇难人数(每个人都有座位号)
相机采集(存储成图片)——》对应100个逃生座位(每个人被重新编号,按照这个变换从0到100重新排)
显示器显示——》100个人逃生回来之后,查找本来在泰坦尼克上的座位号。

在这里插入图片描述
我们需要找到一个映射关系,将原编号的人,映射到小船上的编号。
在这里插入图片描述
我们出了一个政策,不是直接砍掉一部分人,而是要按照重要性采样,越重要的,就有更大的机会被装进小船。

ok,这里的重要性,也就是我们人眼对应的对暗色更加敏感,我们牺牲了更多的不重要的人,牺牲了亮度更高的色度。

那么如何进行这样的映射呢?
查看上图中的采样频率,绿色部分的采样频率是越来越小,也就是在重要的部分,采样非常多次,而不重要的部分,采样次数减少。
而上图中的红色格子,是均匀变化的,因为啥?因为房价的编号,必然遵循线性变换的。这个红色就是对应编码。

采样频率可以用红色值的幂次(1/2.2)绘制:
在这里插入图片描述

这是一种理解方式。

还有一种,就是存储空间有限,我们又对低频新号(暗部)明暗,所以进来让暗部的人进来住。而暗部比如实际是0.2,怎么让其住进变换为0.5的空间呢?使用0.2^(1/2.2)次方即可。

ps中的颜色空间查看:
在这里插入图片描述
在这里插入图片描述

如何查看一个图片使用的颜色空间:
在这里插入图片描述

如何更改一个图片的颜色空间:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ok。到此结束。

那么下面到unity中进行采样显示:
首先是gamma工作流:
在这里插入图片描述
图片默认导入是勾选了sRGB的:
在这里插入图片描述
采样shader:

fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    return col;
}

在这里插入图片描述
在上图中,我们可以看到8中不同的情况下的效果。
可以看到不管图片是什么格式的,只要在线性工作环境下,不勾选srgb则会出现变亮的效果。

下面分析下unity渲染的时候,做了啥,使用renderdoc工具截帧分析。

下面是分析使用snapdragon截帧看图片格式的:
参考:https://editor.csdn.net/md/?articleId=103799344

在这里插入图片描述
首先我们测试,在gamma空间中的,勾选srgb与否的情况。
勾选的时候,截帧看到的图片格式为:
在这里插入图片描述
是RGB8_ETC2,处理之后还是:RGBA8格式。

如果取消勾选sRGB
在这里插入图片描述
是RGB8_ETC2,处理之后还是:RGBA8格式。

实验证明,在unity为gamma工作流的情况下,勾选srgb与否无关紧要。

下面是切换到linear工作流:
首先取消auto graphics api,注意是取消勾选,然后移出opengl es2
在这里插入图片描述
在这里插入图片描述
注意,如果是使用linear工作流,那么,必须在opengl es3以上,所以这里移出了openg es2。然后才能打包测试。

下面是勾选了srgb的结果:截的帧,暗了。然后输入和输出分别是:
SRGB8_ETC2和 SRGB8_ALPHA8
在这里插入图片描述

最后运行结果是正常的。

下面是不勾选srgb的情况:
在这里插入图片描述
终于有一点变化了,输入变成了RGB8_ETC2而输出依然为SRGB8_ALPHA8。

在这里插入图片描述
最终图片变更亮了。

所以总结如下:
1、如果unity使用了gamma工作流,那么无论图片是勾选还是不勾选srgb,那么unity是不做任何处理,不做2.2的变线性,也不做处理之后的1/2.2的操作。

2、如果unity使用了linear工作流,那么如果图片选择了srgb模式,那么unity则为其做2.2的降线性处理,然后在输出的时候,自动进行1/2.2的处理。
而如果图片不勾选srgb模式,那么unity不会为其做2.2的降线性,而在处理之后,缺依然保留做1/2.2的操作。那么图片最终会变亮了。
依然原本图片就是srgb空间,在拍摄或者ps中,就已经做了一次1/2.2的操作。而又因为我们没有勾选srgb,所以没有做2.2的降线性,而在最后输出结果,unity自动做了一次1/2.2的操作,所以连续做了两次1/2.2的操作,于是图片变亮了。

3、如何区分一个图片是否要勾选srgb呢?如果是选用unity的gamma工作流,我们够不够选无所谓,因为unity不会为为我们做任何事情。都是按照怎么输入,怎么来的处理。
而如果是线性工作流,那么则需要人为的操作了,则需要人为判断这个图片是否需要勾选srgb。

4、哪些图片需要勾选srgb呢?勾选了srgb实际上给unity暗示了什么?
对于在线性工作流下,也就是unity使用了linear模式,那么对于那些美术给的漫反射贴图,则是直接在ps中绘制的,而在ps中绘制的图片,则是存储为srgb空间的(与美术商量好)。也就是存储在了(1/2.2的空间中)上曲线中。那么此时导入unity之后,就要知道这个图是非线性的图了。那么则要勾选srgb。

而其他的图,比如法线图、mask图、噪声图,程序纹理,都是线性的图,那么为了避免勾选srgb而造成unity帮我们做了一次2.2的操作,所以要明确告诉unity,这个你不需要转线性了,我自己已经是线性的图了。

总结不知道是否有误,但是暂时认为是对的。

发布了654 篇原创文章 · 获赞 108 · 访问量 36万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 酷酷鲨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览