時(shí)間:2023-05-20 06:28:01 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-05-20 06:28:01 來源:網(wǎng)站運(yùn)營
[Unity Shader]凌波微步效果:Shader "QShader/UnlitShader_04_1"{ Properties { _MainTex ("MainTex", 2d) = "white"{} _Direction ("Direction", vector) = (0,0,0,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; half4 _Direction; float4 _MainTex_ST; struct appdata { float4 position : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 position : SV_POSITION; float2 uv:TEXCOORD0; }; v2f vert (appdata v) { v2f o; v.position.xyz += _Direction.xyz * _Direction.w; o.position = UnityObjectToClipPos(v.position); o.uv = TRANSFORM_TEX(v.uv,_MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex,i.uv); return col; } ENDCG } }}
注意里面的 TRANSFORM_TEX 是為了即時(shí)將變化在屏幕上顯示出來。//噪波算法float noise = frac(sin(dot(v.uv.xy, float2(12.9898, 78.233))) * 43758.5453);
//變換拉伸fixed NdotD = max(0,dot(_Direction,v.normal));v2f vert (appdata v) { v2f o; //噪波算法 float noise = frac(sin(dot(v.uv.xy, float2(12.9898, 78.233))) * 43758.5453); //變換拉伸 fixed NdotD = max(0,dot(_Direction,v.normal)); v.position.xyz += _Direction.xyz * _Direction.w * noise * NdotD; o.position = UnityObjectToClipPos(v.position); o.uv = TRANSFORM_TEX(v.uv,_MainTex); return o; }
實(shí)際就如上所示。至此完整的Shader代碼已經(jīng)出來了。我們增加了一個Color變量用來在貼圖上面添加一個好看的顏色,這里僅是為了美觀,可以去掉。Shader "QShader/UnlitShader_04_2"{ Properties { _Color ("Color",Color) = (0,0,0,1) _MainTex ("MainTex", 2d) = "white"{} _Direction ("Direction", vector) = (0,0,0,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; half4 _Direction; float4 _MainTex_ST; float4 _Color; struct appdata { float4 position : POSITION; float2 uv : TEXCOORD0; half3 normal:NORMAL; }; struct v2f { float4 position : SV_POSITION; float2 uv:TEXCOORD0; }; v2f vert (appdata v) { v2f o; //噪波算法 float noise = frac(sin(dot(v.uv.xy, float2(12.9898, 78.233))) * 43758.5453); //變換拉伸 fixed NdotD = max(0,dot(_Direction,v.normal)); v.position.xyz += _Direction.xyz * _Direction.w * noise * NdotD; o.position = UnityObjectToClipPos(v.position); o.uv = TRANSFORM_TEX(v.uv,_MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex,i.uv); col+=_Color; return col; } ENDCG } }}
這個時(shí)候我們需要一個腳本文件來將物體移動的方向作為參數(shù)傳給Shader的Direction變量,用來動態(tài)顯示殘影。因此新建AfterglowEffect.cs代碼如下using System.Collections;using System.Collections.Generic;using UnityEngine;public class AfterglowEffect : MonoBehaviour { private Material[] mats; private Vector3 prePosition; private Vector3 curPosition; private float deltaTime; // Use this for initialization void Start() { prePosition = curPosition = transform.position; Renderer[] renderers = transform.GetComponentsInChildren<Renderer>(); mats = new Material[renderers.Length]; for (int i = 0; i < renderers.Length; i++) { Renderer renderer = renderers[i]; mats[i] = renderer.sharedMaterial; } } // Update is called once per frame void Update() { curPosition = transform.position; if (curPosition == prePosition) { deltaTime = 0; return; } deltaTime += Time.deltaTime; prePosition = Vector3.Lerp(prePosition,curPosition,deltaTime); Vector3 direction = prePosition- curPosition; for (int i = 0; i < mats.Length; i++) { mats[i].SetVector("_Direction", new Vector4(direction.x, direction.y, direction.z, mats[i].GetVector("_Direction").w)); } }}
這里有兩個需要注意的地方prePosition = Vector3.Lerp(prePosition,curPosition,deltaTime);
我們根據(jù)之前的位置和當(dāng)前的位置通過Lerp函數(shù)做插值,動態(tài)傳入就讓殘影移動的比較平滑。還有一個要注意的是我們的移動方向Vector3 direction = prePosition- curPosition;
一般情況下移動方向是新位置減去之前的位置,但是這樣會導(dǎo)致殘影優(yōu)先移動了過去,什么意思呢?就是下面這個情況關(guān)鍵詞:效果
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。