有些模型多层需要深度写入和深度测试才能正常显示,但是又不去希望这个深度去影响到其他物体,就可以写多一个pass清除深度
例如模型上的ui,在3D相机下,UI不希望有偏移,只用sortorder去控制下
Pass { Name "Z Clear" ColorMask 0 ZWrite On ZTest Always CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float4 vert (float4 vertex : POSITION) : SV_Position { float4 pos = UnityObjectToClipPos(vertex); #if defined(UNITY_REVERSED_Z) pos.z = 1.0e-9f; #else pos.z = pos.w - 1.0e-6f; #endif return pos; } void frag() {} ENDCG }
第二个Pass将模型压扁,偏移,渲染成透明的黑色
Shader "chicai/MeshShadow" { Properties { _DiffuseIntensity("Diffuse Intensity", float) = 1 _SpecularIntensity("Specular Intensity", float) = 1 _Gloss("Gloss", float) = 1 _ShadowPos("ShadowPos", vector) = (0,0,0,0) } SubShader { Tags { "RenderType"="Opaque"} LOD 100 Pass{} //只能在平面上用 Pass { Blend SrcAlpha OneMinusSrcAlpha //透明渲染,会穿透渲染两层,过滤只一层 Stencil { Ref 100 Comp NotEqual Pass Replace } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; float4 _ShadowPos; v2f vert(appdata v) { v2f o; float4 worldPos = mul(unity_ObjectToWorld, v.vertex); float tempPosy = worldPos.y - _ShadowPos.y;//将脚上到头顶的顶点计算到从0开始 worldPos.y = _ShadowPos.y;//地面在世界坐标中的高度,压扁 worldPos.xz += _ShadowPos.xz * tempPosy;//偏移影子 o.pos = mul(UNITY_MATRIX_VP, worldPos); return o; } fixed4 frag(v2f i):SV_TARGET { return fixed4(0,0,0,_ShadowPos.w) ; } ENDCG } } }
可以在SubShader中定义LOD的数值,然后根据设备性能情况设置LOD的值,调用指定的SubShader
SubShader { LOD 300 } SubShader { LOD 200 } SubShader { LOD 100 }
在C#中进行设置 Shader.globalMaximumLOD = 100;
Tags { "RenderType"="Opaque" } LOD 100 Offset -1,-1 //深度偏移 负数推近,正数推远
Properties { [Enum(On,0,Off,1)]_ZWrite("ZWrite",int) = 0 [Enum(UnityEngine.Rendering.CompareFunction)]_ZTest("ZTest",int) = 0 } ZWrite [_ZWrite] ZTest [_ZTest] //默认小于等于
Shader "chicai/LightMode" { Properties { _DiffuseIntensity("Diffuse Intensity", float) = 1 _SpecularIntensity("Specular Intensity", float) = 1 _Gloss("Gloss", float) = 1 } SubShader { Tags { "RenderType"="Opaque"} LOD 100 Pass { Tags { "LightMode"="ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; half3 normal:NORMAL; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; half3 worldNormal:TEXCOORD1; float3 worldPos:TEXCOORD2; }; half _DiffuseIntensity; float _SpecularIntensity; float _Gloss; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = 0; fixed4 Ambient = unity_AmbientSky; half Kd = _DiffuseIntensity; fixed4 LightColor = _LightColor0; fixed3 N = normalize( i.worldNormal ); fixed3 L = _WorldSpaceLightPos0; fixed4 diffuse = Ambient + Kd * LightColor * max(0,dot(N,L)); col += diffuse; //Phong高光 //float3 reflectDir = reflect(-L, N); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos); // fixed4 specularColor = _LightColor0 * _SpecularIntensity * (pow( max( dot(reflectDir,viewDir) ,0),_Gloss) ); // col += specularColor; //Bilnn-Phong高光 fixed4 specularColor = _LightColor0 * _SpecularIntensity * (pow( max(dot(i.worldNormal, normalize(L+viewDir)),0), _Gloss)); col += specularColor; return col; } ENDCG } Pass { Tags { "LightMode"="ForwardAdd" } Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdadd //Builtin keywords used: POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE #pragma skip_variants DIRECTIONAL POINT_COOKIE DIRECTIONAL_COOKIE//剔除不要的变体 #include "UnityCG.cginc" #include "Lighting.cginc"//_LightColor0 _WorldSpaceLightPos0 #include "AutoLight.cginc"//unity_WorldToLight _LightTexture0 衰减贴图 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; half3 normal:NORMAL; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; half3 worldNormal:TEXCOORD1; float3 worldPos:TEXCOORD2; }; half _DiffuseIntensity; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.uv = v.uv; o.worldPos = mul(unity_ObjectToWorld, v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 LightColor = _LightColor0; fixed3 N = normalize( i.worldNormal ); fixed3 L = _WorldSpaceLightPos0; //float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos.xyz,1)).xyz;//距离灯光位置 点光源的 //float atten = tex2D(_LightTexture0, dot(lightCoord,lightCoord)); UNITY_LIGHT_ATTENUATION(atten, 0, i.worldPos);//光照衰减 第二参数计算阴影的 fixed4 diffuse = LightColor * max(0,dot(N,L)) * atten; return diffuse; } ENDCG } } }
Shader "chicai/UIRectClip" { Properties { [PerRendererData]_MainTex ("MainTex", 2D) = "white" {} _Ref("Ref",int) = 0 [Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comp",int) = 0 [Enum(UnityEngine.Rendering.StencilOp)]_StencilOp("Stencil OP",int) = 0 } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } LOD 100 Blend SrcAlpha OneMinusSrcAlpha ColorMask RGBA Stencil { Ref [_Ref] ReadMask 3 Comp [_StencilComp] Pass [_StencilOp] } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ UNITY_UI_CLIP_RECT//内置的宏定义,有RectMask2D会自动对它修改 #include "UnityCG.cginc" #include "UnityUI.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; fixed4 color : COLOR;//UI的颜色 传过来的是顶点颜色 }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; fixed4 color : COLOR; fixed4 worldPos : TEXCOORD1; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _ClipRect;//内置变量 RectMask2D组件 v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.color = v.color; o.worldPos = v.vertex; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); col *= i.color; #if UNITY_UI_CLIP_RECT fixed2 rect = clip(_ClipRect.xy, i.worldPos.xy) * clip(i.worldPos.xy, _ClipRect.zw); col.a *= rect.x * rect.y; //col.a *= UnityGet2DClipping(i.worldPos, _ClipRect); #endif return col; } ENDCG } } }
//Inside C# Monobehaviour script materialPropertyBlock.Clear(); sr.GetPropertyBlock(materialPropertyBlock); materialPropertyBlock.AddFloat(dissolvePropertyID, dissolveValue); sr.SetPropertyBlock(materialPropertyBlock); //Inside the shader Properties{ [PerRendererData] _SliceAmount("Slice Amount", Float) = 0.5 [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {} }
针对多个相同材质,不同属性参数设置,减少性能消耗
Shader "chicai/HotDistort2" { Properties { _DistortTex ("DistortTex", 2D) = "white" {} _Distort ("Distort",Range(0,1)) = 0 _DistortUVSpeedX("DistortUVSpeedX",float) = 0 _DistortUVSpeedY("DistortUVSpeedY",float) = 0 } SubShader { Tags { "Queue"="Transparent" } GrabPass{"_GrabTex"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex:POSITION; fixed2 uv:TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; float4 screenPos :TEXCOORD1; }; sampler2D _DistortTex; float4 _DistortTex_ST; sampler2D _GrabTex; fixed _Distort; float _DistortUVSpeedX,_DistortUVSpeedY; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.screenPos = ComputeScreenPos(o.pos);//转换到[0到w],当uv用需要除以w分量 o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + float2(_DistortUVSpeedX, _DistortUVSpeedY) * _Time.y; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 distortCol = tex2D(_DistortTex, i.uv); fixed2 uv = lerp(i.screenPos.xy / i.screenPos.w, distortCol, _Distort); fixed4 col = tex2D(_GrabTex, uv); return col; } ENDCG } } }
Shader "chicai/HotDistort3" { Properties { _DistortTex ("DistortTex", 2D) = "white" {} _Distort ("Distort",Range(0,1)) = 0 _DistortUVSpeedX("DistortUVSpeedX",float) = 0 _DistortUVSpeedY("DistortUVSpeedY",float) = 0 } SubShader { Tags { "Queue"="Transparent" } GrabPass{"_GrabTex"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex:POSITION; fixed2 uv:TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; }; sampler2D _DistortTex; float4 _DistortTex_ST; sampler2D _GrabTex; fixed _Distort; float _DistortUVSpeedX,_DistortUVSpeedY; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex);//裁剪空间下的 o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + float2(_DistortUVSpeedX, _DistortUVSpeedY) * _Time.y; return o; } fixed4 frag (v2f i) : SV_Target { //i.pos 屏幕的像素坐标 硬件转换 float2 uv = i.pos.xy/_ScreenParams.xy; fixed4 distortCol = tex2D(_DistortTex, i.uv); uv = lerp(uv, distortCol, _Distort); fixed4 col = tex2D(_GrabTex, uv); return col; } ENDCG } } }
混合因子:
One
Zero
SrcColor 源颜色
SrcAlpha 源的Alpha值
DstColor 目标颜色
DstAlpha 目标Alpha值
OneMinusSrcColor
OneMinusSrcAlpha
OneMinusDstColor
OneMinusDstAlpha
常用混合类型
Blend SrcAlpha OneMinusSrcAlpha //传统透明混合
Blend One OneMinusSrcAlpha //预乘透明混合
Blend One One
Blend OneMinusDstColor One //Soft Additive
Blend DstColor Zero //Multiplicative
Blend DstColor SrcColor //2x Multiplicative