写在前面的话(这段不是翻译嗷)

在最开始学习C4D的时候,就被线性工作流程困扰过,之前一阵子还被OC渲染出来的图片总是发暗弄得头大。其实这些都是线性工作流程和伽马值的问题。

之前曾经写过一篇关于线性工作流程的文章,如果你在网站中搜索线性工作流程的话应该还能搜出来。实际上那篇文章因为当时认识有限,很多地方都是错误的。

这篇翻译的原文,算是我在网上找到的讲的最清楚、最全面的一篇文章了,但是要注意这篇文章发布的时间比较早,至少也是2013年发布的,所以一些关于软件上的说法到现在可能不太准,但是理论知识还是可以受用的。

现在翻译如下。

理解线性工作流程

原文地址:点击进入 作者:johan@seazo.no  网站:www.seazo.no

为什么使用线性工作流程?

许多3D艺术家对这个理论迷惑不解,因此很容易觉得也许这个流程并不重要。但是相信我,它很重要。

在线性工作流程中,从渲染设置到后期合成,贯穿整个过程的光和颜色的计算都会被矫正。如果你想让你的渲染达到照片级效果,这是非常必要的。

线性工作流程是用来告诉伽马值是怎样工作的。为了理解这个流程,你需要知道什么是伽马值,伽马值存在的意义和怎么控制伽马值。我会在后面依次详细的解说,现在先来看一些例子。

这是一张没有经过伽马值矫正的图片,在vRay GI模式下渲染的。注意看光并没有在周围反弹并充满整个房间。

这是后期尽量调整伽马值之后的效果,现在光照正确了。但是问题在于现在这张图看上去像是被洗了一样,颜色混合的计算也是错的。地板上的彩球,使用的是Max中纯色的材质球,因为在这里颜色显示是正确的。然而,墙上材质的颜色和壁画的颜色却不是。饱和度和对比度并没有被很好的修复。

这张是在线性工作流程中得到的正确结果。

使用线性工作流程还有一些其他的优势,比如每个通道包含了32bits数据。通常一个图片,比如说JPG格式的图片,每个颜色通道只包含8bits的数据。这些数据量在最终输出的时候是够用了,但是对于后期合成来说,这些数据量还是太少了。你可以观看上面的视频,注意32bit图片在超亮区域中包含的信息。你能看到地板上的反射是怎么被新的像素信息替换的。然而8bit图片并不知道隐藏在白色像素下的信息是什么,因此在曝光度降低时呈现出灰色。尤其是当后期制作景深效果或者辉光效果时,你会注意到32bit图片是怎样显著增加这些效果的质量。

现在让我们回到伽马值这个概念,你需要知道,人眼对光的感知度并不是线性的。换句话说,如果你手中有0.5kg的重物,然后再增加0.5kg,你能很容易判断出重了一倍。但是如果你搬起一个50kg的石头,然后再增加0.5kg,你几乎感受不到有什么区别。同样的情况也出现在听觉和视觉中。

正如你看到的,我们能很容易分辨50w光源和51光源的不同,但是不能分辨出同样相差等级的150w和151w的区别。

这里有一个人对光线敏感度的曲线图。横轴为人对光源的敏感度,纵轴为真实世界光源的变化。

因为我们不能很好的区别太亮光源的区别,所以在整个光谱频段中都用相同的数据密度进行编码是有一些浪费数据的。换句话说,我们不需要在亮部有同样的数据密度,在暗部也一样。实际上,如果你想用线性编码,那么要达到JPG同样质量的话,你需要每个通道14bit数据。你需要在亮部包含更多的信息直到能被人眼区别出来才行。这样一来就浪费数据了。

是的,JPGG编码就是非线性的。实际上,JPEG和其他大多数8bit的图片内部都含有跟人对光源敏感度一样的曲线,这个曲线被称为是Gamma 2.2.

颜色拾取器中颜色的范围是0~255,这个被称为是三色刺激值。

注意看三色刺激值在暗部的逐渐变密,亮部逐渐变宽松。这种结果就是在暗部有更多的信息。在这种方式里,我们依据人眼对光源的敏感度,更多的专注暗部区域的数据处理就可以了。

现在想想,在应用了这套编码之后,图片内部会发生什么事呢?就是整个图片都会被漂白,就像这样:

想一下,为什么8bit图片会看上去像是被漂白了一样呢?你需要知道编码后会发生什么。

在以前,当我们使用CRT显示器的时候,电能的强度会影响像素的亮度。实际上,电能影响像素亮度的法则,几乎和人眼对光源的敏感度正相反(在进行图片编码的时候)。

注意在得到足够的电压来显示亮度的时候,随着电压提高,亮度值变化是非常慢的。正如你看到的那样,这条曲线看上去和人眼对光源敏感度的曲线正相反。

心里想着这两条曲线,然后看下面最终结果是这样的:

在现在的显示器中,电压影响像素亮度的情况是不存在的,但是为了匹配同样的结果,现在的显示器中预先设定了这个伽马曲线,就是为了让最终图片显示是正确的。换句话说,这套理论到现在还是通用的。

所以,在渲染中要注意什么呢?

很简单,当想要实现照片级真实度的渲染时,必须要求所有的图片数据都被转换为线性模式。这是因为这种模式易于计算,而且现实世界中没有非线性光。这意味着当你处理颜色、灯光和贴图时,所有用到的都应该被转为线性空间。之所以被称为是线性空间是因为伽马值曲线不再是一条曲线,而是一条直线,被称为Gamma1.0.

进一步说,在非线性空间下,三色刺激值和实际输出的亮度是不匹配的。

如上图所示,50%三色刺激值与输出的50%亮度并不匹配,输出亮度只有22%。在非线性空间中所有的计算都是错误的。只有在线性空间中才能匹配正确。

现在你可能更好的理解了gamma是怎样工作的,现在来看一下整个流程中应该怎么去处理线性空间。

直接显示线性颜色空间在屏幕上,会让图片看上去被漂白了一样,所以在处理线性空间时候有一个设定,可以让你的显示器在显示你的渲染和通道时是正确的。换句话就是所有数据都在Gamma1下计算,但是肉眼是在gamma2.2下看到内容的。

这个每个渲染器的设置方式都不尽同,你可以去搜索一下你所使用的渲染器的线性空间设置方式。

下面来看一下在合成软件中要怎么处理,首先确保你的图片是32bit,这里推荐EXR文件格式,Photoshop并不能很好的处理EXR,但是大多数合成软件都没有问题。这里拿AE演示。

确保你的工程设置为32bit,这样AE就可以得到图片的全部信息了。

当导入32bit或者任何EXR图片时候,ae就会认为这是一个线性空间下的图片,然后会按着线性空间去处理这个图片。如果你的操作是正确的,图片在AE中的显示也会是正确的。即便图片还没有进行伽马值矫正,AE也会告诉你处理后的最终结果是什么样的。当你导出图片或者视频的时候,AE会确保给它一个正确的伽马值矫正。除非你做了其他设置。

如果你使用了不同的通道,比如说反射通道,你应该使用Add叠加模式,只要图片是在线性空间下,计算就是正确的。Screen叠加模式是一种“假”的模式,用来模拟非线性图片的计算。


(彩蛋)

现在是这样,即使你用的是vRay渲染器,它同样有一些设置上的问题。vRay是使用的适应性采样来渲染,这意味着在暗部区域,vRay不会使用高采样。这种渲染算法叫做vRay DMC采样。这种算法有一个问题就是vRay尝试计算高亮度的区域时,不能得到一个正确的值。这是因为vRay在决定渲染过程中会在内部先用伽马矫正图片。

上图就是vRay不能得到正确值而导致错误渲染的一个例子,注意看一些区域噪点非常严重,即便这个区域很亮,理论上应该得到更多的采样才对。

然而上面这个图才是vRay看到的样子。

为了修复这个问题,需要调整一些设置。

首先,你需要告诉vRay使用线性工作空间,vRay在伽马值设置上有一些过时了,所以必须要把伽马值参数改为2.2,并且勾选上”Don`t affect colors(adaptation only)不要影响颜色(仅在自适应模式下)”框。

注意我没有勾选线性工作空间,这是一个过时的设置,不用理会。

现在vRay的DMC采样器可以得到一个正确的值了。下面是修改设置前后的对比。

这样就正确了。

(完)

4 Comments

  • 头像 三楼说道:

    在oc里面是不是要把伽马设置成2.2就是正确的做法呀

    • 头像 李亦天说道:

      对,response是linear,gamma是2.2

      • 头像 三楼说道:

        就是整个流程只需要把oc设置里面的摄像机成像里的伽马改成2.2就可以了吗?其它啥都不用改了呀,图片作为贴图的时候拖进oc里面默认是有2.2的伽马值的,这样会不会叠加变成双倍的2.2照成贴图过白、灰,就像上面文章中的壁画那种感觉?一直想知道oc的线性工作流程,哥你能告诉我你的流程是怎么操作的吗?非常感谢

      • 头像 三楼说道:

        不好意思,我的英语不好,我翻译了一下你说的,我知道啦,伽马要改成2.2,然后汉化版oc里面的镜头要改成Linear,谢谢你

Leave a Reply