Shader学习的基础知识( 三十)消融效果

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ww1351646544/article/details/88602795

消融效果其实就是噪声纹理+透明度测试,取样阈值在小于0则裁剪掉,0到N显示中间色N到1则正常显示

Shader "Unity Shaders Book/Chapter 15/Dissolve" {
	Properties {
		//消融程度
		_BurnAmount ("Burn Amount", Range(0.0, 1.0)) = 0.0
		//消融宽度
		_LineWidth("Burn Line Width", Range(0.0, 0.2)) = 0.1
		//主图
		_MainTex ("Base (RGB)", 2D) = "white" {}
		//法线纹理
		_BumpMap ("Normal Map", 2D) = "bump" {}
		//边缘纹理颜色1
		_BurnFirstColor("Burn First Color", Color) = (1, 0, 0, 1)
		//边缘纹理颜色2
		_BurnSecondColor("Burn Second Color", Color) = (1, 0, 0, 1)
		//噪声纹理
		_BurnMap("Burn Map", 2D) = "white"{}
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}
		
		Pass {
			//前向渲染
			Tags { "LightMode"="ForwardBase" }

			//关闭剔除
			Cull Off
			
			CGPROGRAM
			
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			
			#pragma multi_compile_fwdbase
			
			#pragma vertex vert
			#pragma fragment frag
			
			fixed _BurnAmount;
			fixed _LineWidth;
			sampler2D _MainTex;
			sampler2D _BumpMap;
			fixed4 _BurnFirstColor;
			fixed4 _BurnSecondColor;
			sampler2D _BurnMap;
			
			float4 _MainTex_ST;
			float4 _BumpMap_ST;
			float4 _BurnMap_ST;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float2 uvMainTex : TEXCOORD0;
				float2 uvBumpMap : TEXCOORD1;
				float2 uvBurnMap : TEXCOORD2;
				float3 lightDir : TEXCOORD3;
				float3 worldPos : TEXCOORD4;
				//定义阴影
				SHADOW_COORDS(5)
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				//采样了这三个纹理
				o.uvMainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
				o.uvBumpMap = TRANSFORM_TEX(v.texcoord, _BumpMap);
				o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap);
				
				//定义转到切线空间的矩阵,存在rotation中
				TANGENT_SPACE_ROTATION;
				//切线空间中顶点指向光照的向量
  				o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
  				
				//世界空间下顶点坐标
  				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  				
				//计算阴影
  				TRANSFER_SHADOW(o);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				//噪声纹理采样
				fixed3 burn = tex2D(_BurnMap, i.uvBurnMap).rgb;
				
				//小于阈值则裁剪掉
				clip(burn.r - _BurnAmount);
				
				float3 tangentLightDir = normalize(i.lightDir);
				//取切线空间中的法线,图片RenderType要改为Normal
				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(tangentNormal, tangentLightDir));

				//取中间值赋予消融的色值效果
				fixed t = 1 - smoothstep(0.0, _LineWidth, burn.r - _BurnAmount);
				fixed3 burnColor = lerp(_BurnFirstColor, _BurnSecondColor, t);
				burnColor = pow(burnColor, 5);
				
				//计算灯光衰减并存在atten中
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
				//颜色融合 step是为了当值为0时,没有消融效果
				fixed3 finalColor = lerp(ambient + diffuse * atten, burnColor, t * step(0.0001, _BurnAmount));
				
				return fixed4(finalColor, 1);
			}
			
			ENDCG
		}
		
		// 渲染阴影部分
		Pass {
			Tags { "LightMode" = "ShadowCaster" }
			
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#pragma multi_compile_shadowcaster
			
			#include "UnityCG.cginc"
			
			fixed _BurnAmount;
			sampler2D _BurnMap;
			float4 _BurnMap_ST;
			
			struct v2f {
				V2F_SHADOW_CASTER;
				float2 uvBurnMap : TEXCOORD1;
			};
			
			v2f vert(appdata_base v) {
				v2f o;
				
				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
				
				o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 burn = tex2D(_BurnMap, i.uvBurnMap).rgb;
				
				clip(burn.r - _BurnAmount);
				
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

猜你喜欢

转载自blog.csdn.net/ww1351646544/article/details/88602795