下面" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > [Unity Shader]凌波微步效果

[Unity Shader]凌波微步效果

時(shí)間:2023-05-20 06:28:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2023-05-20 06:28:01 來源:網(wǎng)站運(yùn)營

[Unity Shader]凌波微步效果:

[Unity Shader]凌波微步效果

相信很多人都看過天龍八部,里面的段譽(yù)有一個技能就是凌波微步:移動的時(shí)候人先到,衣角跟隨其后。說白了就是移動時(shí)有一個殘影跟著他。下面先看下最終效果




下面我們看如何實(shí)現(xiàn)上面的效果。

思路:

1.既然需要移動,那么就需要一個3維(x,y,z三個方向)的數(shù)據(jù)存儲,同時(shí)還需要一個變量用來表示偏移強(qiáng)度。

2.需要一個2d貼圖來做采樣

因此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í)將變化在屏幕上顯示出來。

我們先看下效果




我們創(chuàng)建兩個材質(zhì)球,第一個材質(zhì)球不做任何處理,然后將第二個材質(zhì)球的Direction變量的X修改為2,將兩個物體做個對比觀察。




我們發(fā)現(xiàn)物體向右邊移動了。接下來我們想要的殘影效果還沒有,我們使用噪波算法實(shí)現(xiàn)隨機(jī)偏移的效果。

//噪波算法float noise = frac(sin(dot(v.uv.xy, float2(12.9898, 78.233))) * 43758.5453);





我們看到物體是整體都會被拉伸了,但是我們只需要根據(jù)他的移動方向做拉伸就好,也就是他的前進(jìn)方向做拉伸,背面不做拉伸。怎么做呢?

物體在陽光下會有投影,物體的投影,也就是他的反射光線是可以根據(jù)入射光線以及他的法線來算出。這里就可以將他的不做拉伸的背面理解為他的反射光線。

那么我們就將這個反射光線作為參數(shù)傳入進(jìn)去

//變換拉伸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)先移動了過去,什么意思呢?就是下面這個情況







我們的移動方向是向右邊,但是殘影的方向其實(shí)應(yīng)該是向左邊,也就是反過來,這樣才是對的。

參考:https://connect.unity.com/p/shaderan-li-ding-dian-yun-dong-mo-hu

========================

《游戲AI程序設(shè)計(jì)實(shí)戰(zhàn)》作者

微信公眾號:Unity游戲開發(fā)筆記

http://weixin.qq.com/r/xzs6Im3ERTA6rSlB927V (二維碼自動識別)

QQ群:754814245

歡迎支持我的新書《游戲AI程序設(shè)計(jì)實(shí)戰(zhàn)》




關(guān)鍵詞:效果

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉