易班班级网站建设展示PPT,wordpress php 采集器,青岛网站建设方案案例,做网页一、基本概念
在Unity中通常使用两种方法来实现透明效果 透明度测试#xff08;无法达到真正的半透明效果#xff09;透明度混合#xff08;关闭了深度写入#xff09;
透明度测试
基本原理#xff1a;设置一个阈值#xff0c;只要片元的透明度小于阈值#xff0c;就…一、基本概念
在Unity中通常使用两种方法来实现透明效果 透明度测试无法达到真正的半透明效果透明度混合关闭了深度写入
透明度测试
基本原理设置一个阈值只要片元的透明度小于阈值就会被舍弃不会进行任何处理也不会对颜色缓冲造成影响否则就会按照普通的不透明物体来处理进行深度测试、深度写入等效果极端要么透明要么完全不透明
透明度混合
基本原理使用当前片元的透明度作为混合因子与已经存储在颜色缓冲中的颜色值进行混合得到新的颜色需要关闭深度写入但没有关闭深度测试——深度缓冲是只读的 为什么关闭深度写入如果开启半透明物体在不透明物体前面时半透明物体会挡住不透明物体实现不了半透明效果 可以实现半透明效果
二、渲染顺序
对于半透明物体和不透明物体因为关闭了深度写入所以应该在不透明物体渲染完后再渲染半透明物体对于两个半透明物体应该先渲染远处的再渲染近处的不准确
1.渲染引擎的方法
先渲染所有不透明物体并开启他们的深度测试和深度写入把半透明物体按他们的距离摄像机的远近进行排序再按照从后往前的顺序渲染开启深度测试关闭深度写入 会有更加复杂的重叠情况排序困难
2.Unity的渲染顺序
使用SubShader的 Queue 标签来决定我们的模型将归于哪个渲染队列使用整数索引来表示每个渲染队列号小的越早被渲染 如果想要通过透明度测试来实现效果代码
SubShader{Tags{ Queue AlphaTest}Pass{...}}如果想使用透明度混合
SubShader{Tags{ Queue Transparent}Pass{ZWrite Off //关闭深度写入...}}三、透明度测试
基本原理设置一个阈值只要片元的透明度小于阈值就会被舍弃不会进行任何处理也不会对颜色缓冲造成影响否则就会按照普通的不透明物体来处理进行深度测试、深度写入等通常会在片元着色器中使用 clip函数 进行透明度测试 如果给定参数的任何一个分量是负数则会舍弃当前像素的输出颜色
// Upgrade NOTE: replaced _Object2World with unity_ObjectToWorld
// Upgrade NOTE: replaced mul(UNITY_MATRIX_MVP,*) with UnityObjectToClipPos(*)Shader Custom/Chapter8-AlphaTest
{Properties{_Color (Main Tint, Color) (1,1,1,1)_MainTex (Main Tex, 2D) white{}_Cutoff (Alpha Cutoff, Range(0,1)) 0.5//用于决定我们调用clip进行透明度测试时使用的判决条件}SubShader{Tags {Queue AlphaTest IgnoreProjector True RenderType TransparentCutoff}Pass{Tags{LightMode ForwardBase}CGPROGRAM#pragma vertex vert #pragma fragment frag#include Lighting.cgincfixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _Cutoff;struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos UnityObjectToClipPos(v.vertex);o.worldNormal UnityObjectToWorldNormal(v.normal);o.worldPos mul(unity_ObjectToWorld, v.vertex).xyz;o.uv TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal normalize(i.worldNormal);fixed3 worldLightDir normalize(UnityWorldSpaceLightDir(i.worldPos));fixed4 texColor tex2D(_MainTex, i.uv);//透明度测试clip(texColor.a - _Cutoff);fixed3 albedo texColor.rgb * _Color.rgb;fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse _LightColor0.rgb * albedo * max(0, dot(worldNormal,worldLightDir));return fixed4(ambient diffuse, 1.0);}ENDCG}}FallBack Transparent/Cutout/VertexLit
}
_Cutoff (“Alpha Cutoff”, Range(0,1)) 0.5 用于决定我们调用clip进行透明度测试时使用的判决条件clip(texColor.a - _Cutoff); 做透明度测试判断texColor.a - _Cutoff是否为负数负数的纹理颜色为全透明
四、透明度混合
基本原理使用当前片元的透明度作为混合因子与已经存储在颜色缓冲中的颜色值进行混合得到新的颜色需要使用Unity提供的混合命令 Blend 本节中使用的是Blend SrcFactor DstFactor来进行混合将源颜色混合因子SrcFactor设为SrcAlpha目标颜色混合因子设为OneMinusSrcAlpha 即混合后的新颜色为 D s t C o l o r n e w DstColor_{new} DstColornew SrcAlpha × SrcColor (1-SrcAlpha) × D s t C o l o r o l d DstColor_{old} DstColorold ZWrite Off 关闭深度写入
Shader Custom/Chapter8-AlphaBlend
{Properties{_Color (Main Tint, Color) (1,1,1,1)_MainTex (Main Tex, 2D) white{}_AlphaScale (Alpha Scale, Range(0,1)) 1}SubShader{Tags {Queue Transparent IgnoreProjector True RenderType Transparent}Pass{Tags {LightMode ForwardBase}ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert #pragma fragment frag #include Lighting.cgincfixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _AlphaScale;struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos UnityObjectToClipPos(v.vertex);o.worldNormal UnityObjectToWorldNormal(v.normal);o.worldPos mul(unity_ObjectToWorld, v.vertex).xyz;o.uv TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal normalize(i.worldNormal);fixed3 worldLightDir normalize(UnityWorldSpaceLightDir(i.worldPos));fixed4 texColor tex2D(_MainTex, i.uv);//透明度混合fixed3 albedo texColor.rgb * _Color.rgb;fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse _LightColor0.rgb * albedo * max(0, dot(worldNormal,worldLightDir));return fixed4(ambient diffuse, texColor.a * _AlphaScale);}ENDCG}}FallBack Transparent/VertexLit
} 五、开启深度写入的半透明效果
对于复杂网格的半透明处理避免错误排序方法使用 两个Pass 来渲染模型 第一个开启深度写入但不输出颜色仅仅为了把该模型的深度值写入深度缓存中第二个Pass 进行正常的透明度混合根据第一个Pass可以进行像素级别的深度排序缺点是 多个Pass会造成性能的影响
Shader Custom/Chapter8-AlphaBlend
{Properties{_Color (Main Tint, Color) (1,1,1,1)_MainTex (Main Tex, 2D) white{}_AlphaScale (Alpha Scale, Range(0,1)) 1}SubShader{Tags {Queue Transparent IgnoreProjector True RenderType Transparent}Pass{ZWrite On ColorMask 0}Pass{Tags {LightMode ForwardBase}ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert #pragma fragment frag #include Lighting.cgincfixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _AlphaScale;struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos UnityObjectToClipPos(v.vertex);o.worldNormal UnityObjectToWorldNormal(v.normal);o.worldPos mul(unity_ObjectToWorld, v.vertex).xyz;o.uv TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal normalize(i.worldNormal);fixed3 worldLightDir normalize(UnityWorldSpaceLightDir(i.worldPos));fixed4 texColor tex2D(_MainTex, i.uv);//透明度混合fixed3 albedo texColor.rgb * _Color.rgb;fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse _LightColor0.rgb * albedo * max(0, dot(worldNormal,worldLightDir));return fixed4(ambient diffuse, texColor.a * _AlphaScale);}ENDCG}}FallBack Transparent/VertexLit
}与透明度混合代码几乎一致只是增加了一个Pass
Pass{ZWrite On ColorMask 0}ZWrite On 打开深度写入ColorMask 0 意味着Pass不写入任何颜色通道不会输出任何颜色
六、ShaderLab的混合命令
混合与两个操作数有关源颜色SourceColor和目标颜色DestinationColor 源颜色指片元着色器产生的颜色 S目标颜色指从颜色缓冲中读取到的颜色值 D混合后的颜色 O包含了 RGBA四个颜色通道
1.混合等式和参数
将S和D进行混合的等式——混合等式需要两个一个用于混合RGB一个用于混合A设置混合状态时即设置等式中的 “操作” 和 “因子” 一共有两个等式分别用于混合RGB和A一个等式里有两个因子一个与S相乘一个与D相乘 第一个命令中只有两个因子——RGB和A通道用相同的两个因子 混合因子可以是哪些值呢
2.混合操作
可以使用 BlendOp BlendOperation命令 当使用Min和Max操作时混合因子不起作用的
3.常见的混合类型效果 七、双面渲染的透明效果
观察到其内部结构可以使用Cull指令来控制需要剔除哪个面的渲染图元 Back背对相机的渲染图元不会被渲染Front朝向相机的渲染图元不会被渲染Off关闭剔除功能
Cull Back | Front | Off1.透明度测试的双面渲染
在Pass中使用 Cull Off 来关闭剔除功能即可只在 AlphaTest.shader 里Pass中加一句 Cull Off
2.透明度混合的双面渲染
因为关闭了深度写入如果直接加 Cull Off 的话会造成前后面混乱所以写了两个Pass 与AlphaBlend.shader一样 只在Pass中第一个Pass只渲染背面 添加了Cull Front第二个只渲染正面 添加了Cull BackSubShader是会按照顺序执行Pass