Animation曲线和Shader的结合使用
我们在制作一些复杂特效时,有些变化的参数找不到合适的公式来模拟,那么我们就可以用直观的曲线编辑工具来代替数学公式。这就是我这边文章的思路来源。我结合 闪烁的破旧路灯 案例来演示。
演示
原图
效果图
Shader源码
Shader "ShadersHub/FlickerLight"
{
Properties
{
_NoiseTex ("NoiseTexture", 2D) = "white" {}
_LightColor("LightColor", Color) = (1, 1, 1, 1)
_Intensity("Intensity", Range(0, 10)) = 1.0
}
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
fixed4 _LightColor;
float _Intensity;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _NoiseTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 noise = tex2D(_NoiseTex, i.uv);
fixed4 col = (_LightColor * noise.r) * _Intensity;
return col;
}
ENDCG
}
}
}
Shader源码分析
我们要实现路灯的闪烁效果,只要修改 _Intensity 变量值就行。代码 fixed4 col = (_LightColor * noise.r) * _Intensity; 中,我们加上一个可变函数来影响这个表达式的值,比如改成 fixed4 col = (_LightColor * noise.r) * _Intensity * sin*(_Time.y);,这时的效果是,灯是有规律的闪烁,忽明忽暗。这个并不是我要的破灯的效果。那么我们要将这个函数换成毫无规律的函数,那还真是找不到合适的。这时Animation的手动调整曲线就派上用场了。至于怎么用,一会儿讲到。上面代码中用到了噪声纹理,这个仅仅是为了模型素材做旧效果加上的,这样路灯壳子看上去就会脏兮兮的。
Animaton曲线
unity Animation编辑窗口的功能还是很强大的,它支持编辑对象(绑定了Animation动画的节点)上的各种公开属性。我们Shader中要调节的是 _Intensity 这个值,那么我们要通过Animation来控制这个值,那么中间必须要通过C#脚本做桥梁。所以我们要创建如下的C#脚本。
using UnityEngine;
namespace Assets.ShadersHub.FlickerLight
{
public class FlickerLight : MonoBehaviour
{
public Material LightMaterial;
public float Intensity;
private int propertyID;
void Start()
{
LightMaterial = GetComponent<MeshRenderer>().material;
propertyID = Shader.PropertyToID("_Intensity");
}
void Update()
{
if(LightMaterial == null) return;
LightMaterial.SetFloat(propertyID, Intensity);
}
}
}
这个C#脚本就挂在灯泡(需要闪烁效果)的节点上,然后在这个节点上创建一个Animation,然后针对脚本中的 Intensity 属性做补间动画,并且重点设置下曲线。我的设置如下:
最后点击运行就可以了。
本篇至此完结,欢迎指正交流(或邮件1136468882@qq.com)!