日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果

發(fā)布時(shí)間:2023/12/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

閑暇時(shí)看紙魚實(shí)況,看到游戲中有個(gè)這樣的效果:
視頻鏈接,UP主:薄海紙魚

臥槽,放慢再看一遍:

可以看到,玩家在惹怒Boss后,所有的椅子瞬間消失,Boss戰(zhàn)還未開打就已經(jīng)逼格拉滿了。給玩家留下震撼的印象以及實(shí)力差所帶來的壓抑和絕望。

太帥了!這個(gè)效果我也想要!

實(shí)現(xiàn)思路

仔細(xì)觀察椅子消失瞬間:

想要實(shí)現(xiàn)這個(gè)效果有三個(gè)要求:
一是要剔除片元來達(dá)到物體消融的效果。
二是在剔除片元的操作里設(shè)定剔除的條件。
三是在剔除的邊緣上顏色高亮

看完了馮樂樂女神的書,我們就知道解決第一個(gè)問題需要用到的就是clip函數(shù),該函數(shù)可以剔除指定的片元

clip(x) ///相當(dāng)于下面這句 if(x < 0) {discard; }

ok,上代碼:

Shader "Unlit/DirectionalDissolve" {Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;v2f vert (appdata v){v2f o;//v.vertex.xyz += v.normal * saturate(sin(_Time.w)) * 10;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;//mul(unity_ObjectToWorld,v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);return col;}ENDCG}} }

這里最好開Cull off,否則正面剔除一半時(shí)玩家會(huì)發(fā)現(xiàn)后面早空了。

可以看見關(guān)鍵代碼在這兩句

half dis = i.objPos.y - _DissolveDirection.y; clip(dis);

clip()剔除掉我們不需要的片元。而dis的那句話是用物體對(duì)象的模型坐標(biāo)的y軸與我們給的一個(gè)三維矢量的y軸進(jìn)行相減計(jì)算,軸上相減的結(jié)果小于0的部分片元就會(huì)被剔除掉。

還可以拓展成下面這樣:

half3 dis = i.objPos.xyz - _DissolveDirection.xyz; half discardCondition = * dis.y; clip(discardCondition);

如果想要左右方向的消除,就把dis.y改為x即可。

但要注意,這個(gè)是利用的模型坐標(biāo)系進(jìn)行計(jì)算。如果一個(gè)模型(假設(shè)是人體模型)。他模型坐標(biāo)系的Y軸不是向上而是向前。那你就不能用y軸上的計(jì)算來實(shí)現(xiàn)從頭到腳的順序消失。
你可以考慮用世界坐標(biāo)系解決,世界坐標(biāo)系XYZ軸方向是不會(huì)變的,但同樣會(huì)引入新的問題——物體所在的位置會(huì)影響計(jì)算結(jié)果。這個(gè)問題我目前還沒有比較好的解決方法,看看以后有沒有好兄弟來幫個(gè)忙。

OK,這是目前的效果:

emmmmmm,其實(shí)我想要你們從頭的方向開始消失,而不是腳。。。

Shader "Unlit/DirectionalDissolve" {Properties{..._InverseDir("反向",Range(-1,1)) = 1}...fixed _InverseDir;...fixed4 frag (v2f i) : SV_Target{half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);return col;}ENDCG}} }

這里我用了一個(gè)笨辦法,引入一個(gè)新int屬性,用1和-1來控制消融的方向;想要反方向?乘個(gè)負(fù)一就好。

OK,前兩個(gè)問題搞定了,現(xiàn)在需要解決高亮的問題了。

咱們前面不是利用兩個(gè)矢量相減計(jì)算嗎?小于0的部分被剔除掉了。那我們就再設(shè)定一個(gè)小于某值但大于0的范圍,相減結(jié)果在這個(gè)范圍內(nèi)的,返回的顏色值要發(fā)生改變。
效果如下:

if(discardCondition < _Width) { return fixed4(1,1,1,1); }

圖中的_width值設(shè)為0.1,fixed4(1,1,1,1)代表輸出白色。
我這里用了if,但這種語句是不建議用在shader里的,GPU上做這種邏輯判斷是非常非常奢侈的。
可惜目前沒有想出更好的辦法,只能先把問題放在這了。

最終代碼:

Shader "Unlit/DirectionalDissolve" {Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)_InverseDir("反向",Range(-1,1)) = 1[HDR]_Color ("顏色",Color) = (1,1,1,1)_Width ("寬度",Range(0.0,1.0)) = 0.1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;fixed _InverseDir;fixed4 _Color;fixed _Width;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;return o;}fixed4 frag (v2f i) : SV_Target{//_DissolveDirection.y = sin(_Time.y);half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);if(discardCondition < _Width){ return _Color * col; }return col;}ENDCG}} }

最終效果:

2021/8/15 更新:
在網(wǎng)上找到了puppet_master大佬的文章,他的文章深度和廣度真的不是我這種萌新能比的。
參考文章鏈接,作者:puppet_master
這是看過他的文章后改進(jìn)的代碼:

Shader "Unlit/DirectionalDissolve" {Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)_InverseDir("反向",Range(-1,1)) = 1[HDR]_Color ("顏色",Color) = (1,1,1,1)_Width ("寬度",Range(0.0,1.0)) = 0.1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;fixed _InverseDir;fixed4 _Color;fixed _Width;v2f vert (appdata v){v2f o;//v.vertex.xyz += v.normal * saturate(sin(_Time.w)) * 10;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;//mul(unity_ObjectToWorld,v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{_DissolveDirection.y = sin(_Time.y);half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);//if(discardCondition < _Width)//{ return _Color * col; }//return col;//更好的辦法fixed t = saturate(sign(_Width - discardCondition));return (1 - t) * col + t * _Color * col;}ENDCG}} }

其中,sign函數(shù)長這樣:

當(dāng)x>0,sign(x)=1;
當(dāng)x=0,sign(x)=0;
當(dāng)x<0, sign(x)=-1;
它用這里是為了保證顏色邊界鮮明。如果沒有sign函數(shù)的處理它會(huì)變成這樣:

(這里的材質(zhì)參數(shù)寬度值為0.35,顏色的邊界都如此不明顯。而前面的圖寬度值僅為0.1)

總結(jié)

以上是生活随笔為你收集整理的【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。