今天分享下unity中3D模型的一些Shader。

先来个最简单的,就是上下滚动的纯色流光。

在这里插入图片描述
代码:

Shader "JackyShader/flashShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_centerRange("CenterRange",Range(-2.0, 1)) = 0.5
		_flashColor("FlashColor", Color) = (1, 0, 0, 1)
		_flashHeight("FlashHeight",Float) = 0.1
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
				float objz: TEXCOORD1;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float _centerRange;
			float4 _flashColor;
			float _flashHeight;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.objz = v.vertex.x;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
				// apply fog
				float a = i.objz - (_centerRange - _flashHeight);
				float b = _centerRange + _flashHeight - i.objz;
				float flag = (a*b)/abs(a*b);
				flag = saturate(flag);
				col = lerp(col,_flashColor,flag);
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}

通过调整_centerRange来实现上下滚动。

o.objz = v.vertex.x; 这里使用模型的模型坐标系模型被旋转过所以这里用的是X轴,同学如果想用得改下哈。

flag = saturate(flag);flag被规范为0或1.所以这里变成一个纯色流光,也没有过渡。

下面我们做一个带有颜色过渡效果的流光。

在这里插入图片描述

代码:

Shader "JackyShader/flashShader1"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_centerRange("CenterRange",Range(-2.0, 1)) = 0.5
		_flashColor("FlashColor", Color) = (1, 0, 0, 1)
		_flashHeight("FlashHeight",Float) = 0.1
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
				float objz: TEXCOORD1;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float _centerRange;
			float4 _flashColor;
			float _flashHeight;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.objz = v.vertex.x;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
				// apply fog
				float a = i.objz - (_centerRange - _flashHeight);
				float b = _centerRange + _flashHeight - i.objz;
				float flag = (a*b)/abs(a*b);
				flag = saturate(flag);
				float dis = _flashHeight*2 - abs(i.objz - _centerRange);
				flag = flag*pow(dis*5,3);
				col = lerp(col,_flashColor,flag);
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}

效果舒服很多(当然这个看需求),中间颜色偏中再往两边渐变过渡。

float dis = _flashHeight*2 - abs(i.objz - _centerRange);
离中心点越近dis越大。

flag = flagpow(dis5,3);由上个例子可以得出 flag表示是否在流光区域中。
当不在是为0,则flag计算结果为零。维持流光边界。
当在范围内为1,pow作用在于加速过渡的变化率。

如果我们想过一个带流光贴图的效果,那就是另外一种处理了。需要一张流光的贴图。
我这里在项目中随便找了一张,效果一般但足以做展示。

在这里插入图片描述
代码:

Shader "JackyShader/flashShader2"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_SecondTex("SecondTex", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			sampler2D _SecondTex;
			float4 _SecondTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
				fixed2 suv = i.uv;
				suv.x = suv.x * _SinTime.x;
				fixed4 col1 = tex2D(_SecondTex, suv);
				col = col + col1;
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}

我原本是想找张金色带点金属感觉的,可惜没找到合适的。效果还是比较明显,但是不是很好看。
这里的流光运动是是简单的使用了_sintime.x,如果做项目的时候 最好参考下美术的意见,来调出一个更好的运动变换方式。
这里是抛砖引玉,只是提供一个思路。

假设我们的流光只想做在模型的某个部位,比如说上面这个模型 我只想流光在武器上表现。
这种情况也不复杂,只需要美术同学出一张贴图可以使用黑白两色来便是哪些uv需要做表现流光即可。这里我没有找美术同学帮我制作,所以这里就不演示了。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐