溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

發(fā)布時(shí)間:2021-12-06 11:45:18 來源:億速云 閱讀:153 作者:柒染 欄目:大數(shù)據(jù)

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

角色死亡時(shí)需要一個(gè)漸消效果,最普通的想法就是轉(zhuǎn)成透明物體設(shè)置alpha淡化,然后就會出現(xiàn)這樣的情況。

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

由于模型有分層,會露出衣服下面的部分,而那些部分往往是有缺失的,就算只顯示1秒也非常出戲。而想解決這個(gè)問題也簡單,在前面新增一個(gè)PASS僅繪制深度,就能過濾掉內(nèi)部的模型了。這也是魔獸世界等游戲處理潛行和幽靈人物的方法。

Pass
{
	Tags{ "RenderType"="Transparent" "Queue"="Transparent" }  
	ColorMask 0
}

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

這個(gè)方案的是完美的嗎?其實(shí)并不是。首先這樣做會導(dǎo)致模型以透明方式繪制,無法遮擋地面導(dǎo)致overdraw,但這也算小事。問題在于,這種方法只能針對單Renderer物體,有多個(gè)Renderer的時(shí)候它還是會重疊繪制。如果你希望不重疊,可以將寫深度的PASS的RenderQueue向前設(shè)置,但這樣做的話,所有被這個(gè)物體遮擋的透明物體又都無法顯示了(我的世界的玻璃就是這樣一種狀況),想要兩全其美比較麻煩。合并模型是能解決問題,但是材質(zhì)不同怎么合?分部位換裝怎么可能只用一張貼圖?

更何況,畢竟這是把不透明物體變成了透明物體,這兩者在渲染處理上相差巨大,并不總能保證轉(zhuǎn)換自然(透明度設(shè)置為1時(shí)應(yīng)該保證和之前不透明時(shí)的顯示一致)。而到了延遲渲染管線后,由于透明物體機(jī)理上難以接受光照,只能單獨(dú)處理,或者代價(jià)巨大,就徹底無法使用了。

所以現(xiàn)世代游戲不少都是用的下面這種做法。

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

某一幀

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

實(shí)際上并沒有任何透明像素,僅僅是通過clip讓前方的像素和后方的像素交替顯示,做出一種“看上去是半透”的效果。這樣實(shí)質(zhì)上還是不透明物體渲染,上面說的那些問題就都不存在了。

以下是Shader

Shader "Unlit/AlphaGrid"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_Alpha ("Alpha", Range(0,1)) = 0.1
		_AlphaGridTex ("Alpha Grid Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		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
			{
				float4 vertex : SV_POSITION; 
				float2 uv : TEXCOORD0;
				float4 screenUv : TEXCOORD1;
				UNITY_FOG_COORDS(1)
			};
			
			sampler2D _MainTex;
			float4 _MainTex_ST;
			sampler2D _AlphaGridTex;
			//float4 _AlphaGridTex_ST;
			float _Alpha;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				float4 screenPos = ComputeScreenPos(o.vertex);
				screenPos.xy *= _ScreenParams.xy / 8;//此處不能先除w,會導(dǎo)致插值精度不夠
				o.screenUv = screenPos;
				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);
				float gridAlpha = tex2Dproj(_AlphaGridTex, i.screenUv).a;
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				clip(_Alpha - gridAlpha);
				return col;
			}
			ENDCG
		}
	}
}

注意_AlphaGridTex應(yīng)該設(shè)成全局紋理,我這樣寫只是為了不寫cs代碼。

紋理本身是這樣的一張8x8的alpha8圖片,記錄了每個(gè)8x8屏幕像素的過濾順序。

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

放大:

大數(shù)據(jù)中一種模型淡入淡出時(shí)透明面重疊問題的解決方案

本來想用算法生成,最后還是手繪方便……64個(gè)點(diǎn)而已。

當(dāng)然,這樣做雖然不用額外PASS,但是畢竟是AlphaTest的做法,比不透明物體渲染還是會慢的,頂點(diǎn)上也多了一些計(jì)算壓力,但也就僅此而已了。

(目前手游上,非PowerPR芯片使用discard會導(dǎo)致Early-Z失效,AlphaTest的物體即使被其他物體遮擋也會照樣繪制,導(dǎo)致浪費(fèi)OverDraw,但那也是它被遮擋的時(shí)候才會發(fā)生的情況,這種情況恐怕并不常見,而且即使再差也還是比alphablend強(qiáng)。

而PowerPR芯片則是另外一種情況,雖然不會導(dǎo)致OverDraw浪費(fèi),但是繪制本身變慢了,假如人物frag階段比地面復(fù)雜,半透程度也比較高的話,確實(shí)會有一定的性能問題。所以這并非優(yōu)化,而是一種解決問題的辦法,至于到底是變快還是變慢還要看具體的情況)

當(dāng)然,這種方法并不能用來做常態(tài)的人物半透,久了是必然糊弄不了的,只能用來做漸入漸消。(雖然有游戲確實(shí)在這么搞,諸如FF14,他們也是沒其他的選擇吧)

效果確實(shí)也不能算好,只是特殊情況的特殊選擇。

但多個(gè)選擇總是好的。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI