有些模型多层需要深度写入和深度测试才能正常显示,但是又不去希望这个深度去影响到其他物体,就可以写多一个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