Shader "Unlit/Dissolve" { Properties { _MainTex ("Texture", 2D) = "white" {}//主贴图 _BurnAmount ("BurnAmount",Range(0.0,1.0)) = 0.0 //消融程度 _LineWidth("Burn Line Width",Range(0.0,0.2)) = 0.1 //越大消融边界的颜色越多 _BumpMap("Normal Map",2D) = "bump"{} //法线贴图 _BurnFirstColor("Burn First Color",Color)=(1,0,0,1) //消融边界颜色1 _BurnSecondColor("Burn Second Color",Color) = (1,0,0,1) //消融边界颜色2 _BurnMap("Burn Map",2D) = "white"{} //噪音贴图 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags{"LightMode" = "ForwardBase"} Cull Off//双面渲染 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" struct v2f { float4 vertex : SV_POSITION; float2 uvMainTex:TEXCOORD0; float2 uvBumpMap:TEXCOORD1; float2 uvBurnMap:TEXCOORD2; float3 lightDir:TEXCOORD3; float3 worldPos:TEXCOORD4; }; sampler2D _MainTex; float4 _MainTex_ST; float _BurnAmount; float _LineWidth; sampler2D _BumpMap; float4 _BumpMap_ST; float4 _BurnFirstColor; float4 _BurnSecondColor; sampler2D _BurnMap; float4 _BurnMap_ST; v2f vert (appdata_full v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uvMainTex = TRANSFORM_TEX(v.texcoord, _MainTex); o.uvBumpMap = TRANSFORM_TEX(v.texcoord, _BumpMap); o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap); TANGENT_SPACE_ROTATION;//使用切线空间的法线,把光照方向转到切线空间来计算漫反射 o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } fixed4 frag (v2f i) : SV_Target { fixed3 burn = tex2D(_BurnMap,i.uvBurnMap).rgb; clip(burn.r - _BurnAmount);//根据噪音贴图的取样结果 剪裁掉片元 消融 <0就会舍弃掉 float3 tangentLightDir = normalize(i.lightDir); fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap, i.uvBumpMap)); fixed3 albedo = tex2D(_MainTex, i.uvMainTex).rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentLightDir, tangentNormal)); //t为0表示为正常颜色 _LineWidth越大时smoothstep计算出来的结果就越小几率为1 //t为0的几率就越小,所以边缘的颜色范围会越大 fixed t = 1 - smoothstep(0.0, _LineWidth, burn.r - _BurnAmount); fixed3 burnColor = lerp(_BurnFirstColor, _BurnSecondColor, t);//两种颜色渐变,模拟燃烧腐蚀什么的 burnColor = pow(burnColor, 5);//让边缘效果越好 UNITY_LIGHT_ATTENUATION(atten, i,i.worldPos); //为0为正常颜色,step保证_BurnAmount为0时全是正常颜色 fixed3 finalColor = lerp(ambient + diffuse * atten, burnColor, t*step(0.0001, _BurnAmount)); return fixed4(finalColor, 1); } ENDCG } } }