UnityShander开发之透明

本文深入探讨Unity Shader中透明渲染的关键点,包括深度写入、渲染顺序、混合因子及双面渲染的应用技巧,旨在帮助开发者解决透明效果下常见的视觉问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

透明中需要关注的点

1.深度写入

简单来说就是缓存像素的深度值,通过比较深度值,较浅的显示,较深的被覆盖。

1.1 两物体交叉时

1.1.1 无深度写入时

在这里插入图片描述

会有当红色的面片的中心点低于白色的面片时:
出现在交叉区域一直都是白色显示在上方,而实际上是有时候白色在上方,后时候红色在上方

这是由于没有深度的数据,较后渲染的面片会直接将较先渲染的面片作为底色进行透明度混合

1.1.2 有深度写入时

在这里插入图片描述
会有当红色的面片的中心点低于白色的面片时:
出现红色面片盖住白色面片区域红色直接覆盖了,而白色面片盖住红色的区域正常显示

这是由于有深度的数据,较后渲染的面片会因为深度比较浅,导致颜色值无法写入颜色缓冲区、进行颜色透明度混合

1.1.3 Unity中的使用

ZWrite Off 为关闭
ZWrite On 为开启

SubShader {
		Tags {"Queue"="Transparent" }

		Pass {
			...
			ZWrite Off
			...
			}
		}

1.2 自身有复杂层次关系的

1.2.1 无深度写入时

在这里插入图片描述

1.2.2 有深度写入时

在这里插入图片描述
该情况较为特殊,由于上面提到的深度写入时写在一个通道里面的,而一边自身渲染一边获取深度是不行的,所以需要再创建一个只用作深度写入的通道。

1.2.3 Unity中的使用
SubShader {
		Tags {"Queue"="Transparent" }
		
		// Extra pass that renders to depth buffer only
		 Pass {
		 	ZWrite On
		 	ColorMask 0
		 }
		
		Pass {
			...
			ZWrite Off
			...
			}
		}

2.渲染顺序

物体类型深度写入颜色写入
半透明物体不开启开启
不透明物体开启开启

复杂半透明的物体通常会关闭单通道的深度写入(如表格所示),不会往深度缓冲区写入数据,那么这个时候由两个物体,分别为透明物体A(圆形)不透明物体B(正方形),且A在B前方。

2.1 举例说明

1.当B在A之前渲染
在这里插入图片描述

B先渲染 :B访问深度缓冲区与颜色缓冲区,都没有数据,直接写入
A后渲染:A访问颜色缓冲区,有颜色,通过混合因子进行颜色混合

出来的渲染图是合理的

2.当A在B之前渲染

在这里插入图片描述

A先渲染:A访问颜色缓冲区,无数据,直接写入数据
B后渲染:B访问深度缓冲区,无数据,直接写入,根据深度缓冲区的数据,A无深度,B将会直接将A的颜色缓冲盖掉

这样子出来的渲染图明显是错误的

所以,在透明的开发中,渲染的顺序十分重要

2.2 在Shader需要的配置

名称索引号描述
Background1000这个渲染队列会在任何其他队列之前被渲染,我们通常使用该队列来渲染那些需要绘制在背景上的物体
Geometry2000默认渲染队列,大多数物体都是用这个队列,不透明物体使用这个队列
AlphaTest2450需要透明度测试的物体使用这个队列
Transparent3000这个队列中的物体会在所有Geometry和AlphaTest物体渲染后,再按从后往前的顺序进行渲染,任何使用了透明度混合(例如关闭了深度写入)都应使用该队列
Overlay4000该队列用于实现一些叠加效果,任何需要在最后渲染的物体都应该使用该队列

通常需要在子着色器中设置渲染队列为 “Transparent”,这样Unity在渲染时就会将该物体放到Transparent渲染队列中

SubShader {
		Tags { "Queue"="Transparent" }
		Pass{
				...
		}
}

3.混合因子

3.1 语义

语义描述
Blend Off关闭混合
Blend SrcFactor DstFactor开启混合,并设置混合因子,源颜色(该片元产生的颜色)会乘于SrcFactor,而目标颜色(已经存在于颜色缓存的颜色)会乘以DstFactor,然后把两者相加后再存入颜色缓冲中
Blend SrcFactor DstFactor,SrcFactorA DstFactorA和上面几乎一样,只是使用不同的因子来混合透明通道
BlendOp BlendOperation并非是把源颜色和目标颜色简单地加减后混合,而是使用BlendOperation来对他们进行其他操作

3.2 参数

参数描述
One因子为 1
Zero因子为 0
SrcColor因子为源颜色值,当用于混合RGB通道的混合等式时,使用SrcColor的RGB分量作为混合因子;当用于混合A的混合等式时,使用SrcColor的A分量作为混合因子
SrcAlpha因子为源颜色的透明度值(A通道)
DstColor因子为目标颜色值。当用于混合RGB通道的混合等式时,使用DstColor的RGB分量作为混合因子;当用于混合A的混合等式时,使用DstColor的A分量作为混合因子
DstAlpha因子为目标颜色的透明度值(A通道)
OneMinusSrcColor因子为(1-源颜色)。当用于混合RGB通道的混合等式时,使用结果的的RGB分量作为混合因子;当用于混合A的混合等式时,使用结果的A分量作为混合因子
OneMinusSrcAlpha因子为(1-源颜色的透明度值)
OneMinusDstColor因子为(1-目标颜色)。当用于混合RGB通道的混合等式时,使用结果的的RGB分量作为混合因子;当用于混合A的混合等式时,使用结果的A分量作为混合因子
OneMinusDstAlpha因子为(1-目标颜色的透明度值)
操作描述
Add将混合后的源颜色和目标颜色相加。默认的混合操作。使用的混合等式是: O r g b = S r c F a c t o r ∗ S r g b + D s t F a c t o r ∗ D r g b O_{rgb}=SrcFactor *S_{rgb}+DstFactor *D_{rgb} Orgb=SrcFactorSrgb+DstFactorDrgb O a = S r c F a c t o r A ∗ S a + D s t F a c t o r A ∗ D a O_{a}=SrcFactorA *S_{a}+DstFactorA *D_{a} Oa=SrcFactorASa+DstFactorADa
Sub将混合后的源颜色减去混合后的目标颜色。使用的混合等式是: O r g b = S r c F a c t o r ∗ S r g b − D s t F a c t o r ∗ D r g b O_{rgb}=SrcFactor *S_{rgb}-DstFactor *D_{rgb} Orgb=SrcFactorSrgbDstFactorDrgb O a = S r c F a c t o r A ∗ S a − D s t F a c t o r A ∗ D a O_{a}=SrcFactorA *S_{a}-DstFactorA *D_{a} Oa=SrcFactorASaDstFactorADa
RevSub将混合后的目标颜色减去混合后的源颜色。使用的混合等式是: O r g b = D s t F a c t o r ∗ D r g b − S r c F a c t o r ∗ S r g b O_{rgb}=DstFactor *D_{rgb}-SrcFactor *S_{rgb} Orgb=DstFactorDrgbSrcFactorSrgb O a = D s t F a c t o r A ∗ D a − S r c F a c t o r A ∗ S a O_{a}=DstFactorA *D_{a}-SrcFactorA *S_{a} Oa=DstFactorADaSrcFactorASa
Min使用源颜色和目标颜色中较小的值,是逐分量比较的,使用的混合等式为: O r g b a = ( m i n ( S r , D r ) , m i n ( S g , D g ) , m i n ( S b , D b ) , m i n ( S a , D a ) ) O_{rgba}=(min(S_r,D_r),min(S_g,D_g),min(S_b,D_b),min(S_a,D_a)) Orgba=(min(Sr,Dr),min(Sg,Dg),min(Sb,Db),min(Sa,Da))
Max​​​​​​​ O r g b a = ( m a x ( S r , D r ) , m a x ( S g , D g ) , m a x ( S b , D b ) , m a x ( S a , D a ) ) O_{rgba}=(max(S_r,D_r),max(S_g,D_g),max(S_b,D_b),max(S_a,D_a)) Orgba=(max(Sr,Dr),max(Sg,Dg),max(Sb,Db),max(Sa,Da))

3.3 在Unity中的使用

在通道内设置

SubShader {
		Tags { "Queue"="Transparent" }
		Pass{
				...
				Blend SrcAlpha OneMinusSrcAlpha
				...
		}
}

4.双面渲染

将双面的面片都渲染出来

4.1 在Unity中的使用

SubShader {
		Tags { "Queue"="Transparent" }
		Pass{
				...
				Cull Front
				...
		}
		Pass{
				...
				Cull Back
				...
		}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值