啥是预乘?——Nuke中的Premult(预乘)和Unpremult(预除)

本文不定期更新,最新内容请访问:https://www.shuaiqi.me/2019/04/03/shashiyuchengnukezhongdepremultyuchengheunpremultfanyucheng/

2019.10.26 增加图四图五,以及一些小的修改

2019.05.24 增加了预乘的历史模块和一些图片,修正了部分错误及措辞。

写在前面——致从After Effects转到Nuke的Boys & Girls

图一——RGB通道

图二——Alpha通道

图三——预乘后的RGB通道

首先明确,在After Effects和Nuke中,RGB和Alpha通道都是相互独立存在的。Ok,在After Effects中,在图层上创建一个蒙版(Alpha),那么在RGB上会立即体现出来(会被立即预乘)。而在Nuke中,在Alpha通道上做改动,不会立即对RGB产生影响,除非手动做出预乘的动作。比如,图一RGB通道上是一位哲学家。如果在After Effects中, 对其Alpha进行改动,在上面画上象征自由的印记♂ ,这时软件自动预乘,此时RGB通道就会变成图三。但是如果在此Nuke中进行此Alpha的修改,RGB不会有任何变化,仍保持图一的状态,但在此时加入预乘动作,图一的RGB通道就会变成图三,就达到了预乘的效果。

啥是预乘(Premult)?

图四——Original RGB

图五—— Premultiplied Image

在正式回答这个问题之前,我们先回顾一下预乘(Premultiply)的历史——在上世纪CG行业刚刚兴起时,CG图像一般被渲染成两个图层(Pass),一是原生RGB层 (如图四) ,它携带着每个像素的原生颜色信息,注意它是没有抗锯齿的,边缘都是实打实的;二是透明度层,它携带着每个像素的透明度信息(如图),比如抗锯齿信息,动态模糊信息和半透明区域信息等。早期的合成师收到这两个图层后,会先将原生RGB层与透明度层相乘,以得到带有抗锯齿的图像。后来,CG技术的进步使得透明度层可以作为一个通道(Channel)合并到了RGB层(Pass),也就成了我们现在所说的RGBA层(可以理解为直通Alpha图像),但是这时合成师仍然需要将RGB通道与Alpha通道相乘以获得抗锯齿等效果;再得益于渲染技术的发展和特效制作流程的进步,渲染软件执行了将原生RGB与Alpha相乘的任务,这样渲染出来的图像就带抗锯齿了 (如图五) 。这时再给到合成师的CG图像,在渲染阶段已经做了原生RGB与Alpha相乘的流程,已经不需要合成师再做,他们管它叫做预先乘过的图像(Premultiplied Image),“预乘”这个词从此出现,沿用至今。从算法上来说,预乘与普通的RGB与Alpha的乘法运算并无二致,而因为这个历史沿袭的叫法,只要是RGB与Alpha相乘的这种运算都叫预乘了。

我们再来回到预乘本身,用算法表示即:假如有通道值(R, G, B, A),那么预乘之后通道值为(RA, GA, BA, A);在画面(RGB)上最直观的表现就是A值为1的部分被完全保留,A值为0的部分被完全抛弃(变为黑色),0-1部分按照值得到不同程度的呈现。

为什么要预乘?

1.使得画面(RGB)能够按照Alpha的指示进行正常显示,这通常适用于素材没有Alpha或者素材为直通Alpha的情况。
2.在合成中,预乘存在的意义还有顺应Nuke的工作流程,比如在Merge的Over模式下,其算法为A+B(1-a)(此时的A,B表示素材A,素材B,a表示素材A的Alpha),这就决定在某些流程中必须要预乘,否则就会出现图像重叠等错误。


3.抗锯齿,平滑边缘。在处理直通Alpha图像(如图四)时,预乘的过程中就实现了平滑边缘(如图五)。不过,现在大多数CG软件输出的CG图像都是预乘Alpha图像而非直通Alpha图像,注意对于预乘Alpha图像不要再预乘,否则双重预乘会造成边缘黑边的出现。

啥是预除(Unpremult)?

在算法上表示即:将已经预乘的图像再除回去,假如有(RA, GA, BA, A),那么反预乘/预除(Unpremult)之后,则为(R, G, B, A),在画面上呈现就是它会给到最直观的没有半透明部分(Alpha影响)的RGB图像。

为什么要预除?

1.针对于已经预乘过的图像,调色前和进行颜色空间转换前需要进行反预乘,在调色完成后再预乘回去。为什么需要这个步骤?主要有两个目的:目的一:主要是为了避免黑白边等边缘破坏问题(是否预乘对于alpha为1的部分没有影响)。假如我们有已预乘的边缘像素RGBA值为(0.3, 0.3, 0.3, 0.5),如果我们直接用Grade调色节点Offset设为0.4,那么此时的像素值为(0.7, 0.7, 0.7, 0.5);但是如果我们先用反预乘节点,此时像素值为(0.6, 0.6, 0.6, 0.5),我们再进行调色,此时像素值为(1, 1, 1, 0.5),然后再进行预乘,此时像素值为(0.5, 0.5, 0.5, 0.5)。现在有两个值,一是未经反预乘调色的值(0.7, 0.7, 0.7, 0.5),二是经过反预乘调色的值(0.5, 0.5, 0.5, 0.5),一比二要更亮一些,这就是白边出现的部分原因,并且在实际调色过程中运算远不止加法这么简单,所以在调色前加入反预乘来避免边缘破坏是很有必要的。那么未经反预乘就调色犯了什么错误呢?在于忽略了Alpha这个权重在画面中的作用。目的二:还是假设要Offset 0.4,那么如果在已经预乘的图像上调色会发现原本RGBA都为0的黑色区域也提升了0.4,这显然不是我们想要的结果,加入反预乘则会解决这个问题。
2.扩边。这属于Unpremult的一种特殊用法,在已预乘图像的RGBA图层进行Blur,然后再Unpremult,这是利用Unpremult扩边的大致思路。可以应用于扩边,去除污点以及蓝绿幕Cleanplate的制作等。

关于Read节点中的Premultiplied

在Read节点的Colorspace栏中,有Premultiplied选框。首先Nuke是在Linear的色彩空间中进行工作的,所以在读取各种图像文件时需要进行色彩空间的转换,而这种转换是通过特定的Lut来实现的,其实这也相当于一次调色,勾选Premultiplied框即告知Nuke此图像是预乘过的,那么Nuke在色彩空间转换时会先反预乘,转换完成后再预乘回去。可以解决素材导入时的边缘破坏(黑白边)问题。

写在后面

预乘是一个历史比较悠久的概念,笔者对其认识尚浅,且本文带有较多的个人思考,难免纰漏之处,敬请指正。

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值