unity 3D模型流光Shader
·
今天分享下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需要做表现流光即可。这里我没有找美术同学帮我制作,所以这里就不演示了。
更多推荐
所有评论(0)