章程

透明通道中预乘和非预乘的原理 (premultiply 和 non premultiply)


由于特效朋友也反映了一些在特校透明贴图里,透明出现黑边/白边,衰减不够准确等问题.解决问题以后,顺便整理一下原理.

所谓premultiplynon- premultiply就是shader在处理透明渲染的时候,是否从贴图里拾取alpha通道,把它乘在rgb通道上,在透明的同时作颜色上的衰减。

如果shader里是premultiply的设置,那么纹理就应该是这样的:

1

既然shader里预乘过alpha通道了,那纹理上就不用乘了。

如果Shader是非预乘,non-permultiply的Shader,那贴图应该是这样配合的。

2

由于shader是不乘的,所以贴图上要手动乘,做rgb通道的渐变。
无论是那种设置,目的都是为了得到以下的结果:

3

总之shader和纹理在预乘非预乘上正确的配对,才能得到最精确的透明效果。

范例

4

直接存透明的png因为缺乏对rgb通道被透明掉得部分的观察,碰上非预乘的shader,就会有黑边白边的问题出现,所以应该用superpng, 把所有贴图的rgba通道分开存,这样便于观察,能避免很多问题。

这里有还一个常见错误,美术一般不是太敏感。就是在photoshop里已经预乘的贴图,用到预乘的shader里面,这样衰减被乘了两次,虽然没有出现致命的视觉效果错误,但是渐变被严重缩短,已经不是美术原来画的效果了。

5

可以看到,最后被透掉的最终效果由于被乘了两次而大大缩短了。

所以,假设shader就是预乘的,不能修改,而美术手上也只有一张被预乘过的纹理,如果又需要比较精确的渐变,可以通过以下方式,在photoshop里除一次,导出,就没有问题了。

6

最后的效果就是alpha通道里美术所需求的渐变,非常精确。