unityshader 消融效果

代码,讲解都在注释上面了:
冯乐乐的《unity shader 入门精要》:
相关知识:

  • 透明度
  • 阴影计算
  • 普通光照
  • 法线贴图
Properties
	{
		_BurnAmount("BurnAmount",Range(0,1)) = 0
		_LineWidth("LineWidth",Range(0,0.2)) = 0.1
		_MainTex("MainTex",2D) = "white"{}
		_BumpMap("BumpMap",2D) = "white"{}
		_BumpFirstColor("BumpFirstColor",Color) = (1,1,1,1)
		_BumpSencondColor("BumpSencondColor",Color) = (1,1,1,1)
		_BurnMap("BurnMap",2D) = "white"{}
	}
	SubShader
	{
		pass {
				Tags{"LightMode" = "ForwardBase"}
				Cull Off
				//cg语言开始编写
				CGPROGRAM

				//片段程序
				#pragma fragment frag
				#pragma multi_compile_fwdbase

				struct Output {
						float4 pos:POSITION;
						float2 uvMainTex:TEXCOORD0;
						float2 uvBumpMap:TEXCOORD1;
						float2 uvBurnMap:TEXCOORD2;
						float3 lightDir:TEXCOORD3;
						float3 worldPos:TEXCOORD4;
						//阴影
						SHADOW_COORDS(5)
				};
				Output vert(Input v)
				{
					Output o;
					o.pos = UnityObjectToClipPos(v.vertex);
					o.uvMainTex = TRANSFORM_TEX(v.uv, _MainTex);
					o.uvBumpMap = TRANSFORM_TEX(v.uv, _BumpMap);
					o.uvBurnMap = TRANSFORM_TEX(v.uv, _BurnMap);
					//切线空间转换rotation
					TANGENT_SPACE_ROTATION;
					o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
					o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
					//阴影计算
					TRANSFER_SHADOW(o);
					return o;
				}
				fixed4 frag(Output i) :SV_Target
				{
					fixed4 burn = tex2D(_BurnMap,i.uvBurnMap);
					//为了全部剪除,需要对burn.a - _BurnAmount进行差值判断
					float val = burn.a - _BurnAmount < 0.01 ? -1 : burn.a - _BurnAmount;
					//裁剪
					clip(val);
					//采样物体本身纹理图
					float3 albedo = tex2D(_MainTex, i.uvMainTex).xyz;

					//计算切线空间数据
					float3 tangentLight = normalize(i.lightDir);
					float3 tangentNormal = UnpackNormal(tex2D(_BumpMap, i.uvBumpMap));
					//环境光
					fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
					//切线空间下的漫反射,也可以自己添加镜面高光,为了法线贴图
					fixed3 diff = _LightColor0.rgb*albedo*max(0, dot(tangentLight, tangentNormal));

					//裁剪边缘的颜色区域宽度
					fixed t = 1 - smoothstep(0, _LineWidth, burn.a - _BurnAmount);
					fixed3 burnColor = lerp(_BumpFirstColor, _BumpSencondColor, t);
					burnColor = pow(burnColor, 5);

					//阴影计算atten
					UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

					fixed3 finalColor = lerp(ambient + diff * atten, burnColor, t*step(0.0001, _BurnAmount));

					return fixed4(finalColor, 1);
				}
				ENDCG
		}
		//可以试着将这个pass注释掉,看效果,会发现阴影没有随着裁剪而变化
		pass{
			
		Tags{"LightMode" = "ShadowCaster"}
			//cg语言开始编写
			CGPROGRAM

			//片段程序
			#pragma fragment frag
			#pragma multi_compile_shadowcaster
			struct Output {
				V2F_SHADOW_CASTER;
				float2 uvBurnMap:TEXCOORD2;
			};
			Output vert(Input v)
			{
				Output o;
				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
				o.uvBurnMap = TRANSFORM_TEX(v.uv, _BurnMap);
				return o;
			}
			fixed4 frag(Output i) :SV_Target
			{	
				fixed4 burn = tex2D(_BurnMap,i.uvBurnMap);
				float val = burn.a - _BurnAmount < 0.01 ? -1 : burn.a - _BurnAmount;
				clip(val);
				SHADOW_CASTER_FRAGMENT(i)//投射阴影
			}
			ENDCG
		}

			CGINCLUDE

				//在逻辑中申明顶点和片段://编译申明函数
				//顶点程序
				#pragma vertex vert
				#include "Lighting.cginc"
				#include "AutoLight.cginc"
				#include "UnityCG.cginc"
				struct Input {
					float4 vertex:POSITION;
					float2 uv:TEXCOORD0;
					float3 normal:NORMAL;
					float4 tangent:TANGENT;
				};
				
				sampler2D _MainTex;
				float4 _MainTex_ST;
				sampler2D _BumpMap;
				float4 _BumpMap_ST;
				sampler2D _BurnMap;
				float4 _BurnMap_ST;

				float _BurnAmount;
				float _LineWidth;
				float4 _BumpFirstColor;
				float4 _BumpSencondColor;
				
			ENDCG

	}
	 FallBack "Specular"//影子

效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/QO_GQ/article/details/118441283