除了仅在屏幕上绘制颜色外,我们还可以保留屏幕上以前的某些颜色,使对象看起来是透明的。 我将说明如何在不带照明的基本着色器中实现此效果。
为了使透明对象正确呈现,我们告诉unity对象是透明的。 为此,我们将更改渲染类型以及队列。 通过更改队列,我们确保渲染的材质晚于不透明的材质。 如果不是这种情况,则位于透明对象后面的不透明对象必须在透明对象的上方绘制,并将其完全覆盖。
接下来,我们定义“混合模式”,它定义现有颜色和新颜色如何相互融合。 混合模式由2个关键字定义,第一个定义与新颜色相乘的值,第二个定义与旧颜色相乘的值。 将颜色相乘后,将它们加在一起并绘制结果。
渲染不透明材质时,混合模式为1零,因为我们采用了所有新值而没有采用旧值。 在透明材质中,我们要基于alpha值(我们返回的颜色中的第4个数字,到目前为止没有做任何事情)进行混合。 因此,我们将第一个混合值设置为源Alpha,在这种情况下,源是着色器的输出。 第二个值必须是该值的倒数,所以它是一个减去源alpha的值。
可以在子着色器或着色器通道中定义混合模式,但必须在hlsl区域之外。
Blend SrcAlpha OneMinusSrcAlpha
我将向您展示2个有关其工作原理的小例子,这样可能更清楚:
当我们的片段着色器返回的alpha值为0.5时,混合将使用新颜色的一半和旧颜色的1-0.5(0.5),将它们均匀混合(当在黑色上绘制白色时,它将是中等灰色)。
当我们的片段着色器返回的Alpha值为0.9时,混合将采用90%的新颜色并添加10%的旧颜色,从而使旧颜色几乎不可见。
通过这些更改,我们的着色器已经可以用于透明材质。 由于我们在片段着色器中保留了Alpha通道,因此我们可以设置色调颜色的Alpha,它将成为材质的Alpha(前提是您使用的纹理不使用Alpha通道)。
我们在这里要做的另一件事是禁用z写入。 通常,在渲染对象时,它会将与相机的距离写到纹理中,以告诉后面的其他对象不要在其上绘制。 但是,这不适用于透明对象,因为透明对象不会完全遮挡它们后面的所有内容 可以在subshader或shader通道中定义是否写入Z缓冲区。
Shader "UnityShader/Basic_Transparency"