溫馨提示×

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

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

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

發(fā)布時(shí)間:2021-09-04 16:18:50 來(lái)源:億速云 閱讀:1437 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法”,在日常操作中,相信很多人在Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

紋理壓縮

如果使用Spine的默認(rèn)輸出格式,是這樣的

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

但是輸出紋理的格式必須是未壓縮的RGBA,如果你將圖片格式改為ETC2或者ASTC,就會(huì)變成這樣:

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

而這是絕對(duì)不能容忍的畫(huà)面瑕疵。

ETC2的壓縮質(zhì)量絕不至于這樣差,之所以會(huì)變成這樣,在于Spine的默認(rèn)輸出格式是勾選了“預(yù)乘(premultiplied alpha)”參數(shù)的,這種做法會(huì)將圖片原始的RGB通道預(yù)先乘以透明度保存成文件,顯示時(shí)再用特殊的Shader乘回去。而ETC2的壓縮算法并沒(méi)有考慮過(guò)這種情況,由此導(dǎo)致了壓縮質(zhì)量降低。

而之所以Spine要使用預(yù)乘(premultiplied alpha),目的是為了解決透明圖片的采樣問(wèn)題。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

如圖,左邊的像素點(diǎn)是純透明,右邊的像素點(diǎn)是白色點(diǎn),如果在紅點(diǎn)處采樣,獲得的顏色值就是(0.5,0.5,0.5,0.5)

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

而正確的顏色值應(yīng)該是(1,1,1,0.5),因?yàn)樽兓闹粦?yīng)該是透明度,不能因?yàn)檫_(dá)到邊緣,連圖像本身的亮度都降低。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

預(yù)乘是能完美的解決這個(gè)問(wèn)題的,它生成的像素點(diǎn)是(0x0,0x0,0x0,0),(1x1,1x1,1x1,1),采樣后的顏色是0.5,0.5,0.5,0.5,但還原的時(shí)候還要再除以透明度,所以結(jié)果是(0.5/0.5,0.5/0.5,0.5/0.5,0.5)=(1,1,1,0.5),能夠得到正確的值。

而除了預(yù)乘以外,還有另一個(gè)方法,就是讓透明度為0的區(qū)域也填充有顏色。雖然有顏色,但因?yàn)橥该鞫仁?,看上去依然是透明,如圖:

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

這種操作叫做出血(bleeding)。排除掉透明通道,可以看到出血后圖片會(huì)復(fù)制邊緣的像素到臨近的透明區(qū)域。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

雖然在某些特殊的采樣角度下會(huì)有錯(cuò)誤,但大部分情況沒(méi)問(wèn)題,而這種方法可以正常支持壓縮紋理。

Bleeding可以在Spine的輸出窗體設(shè)置,也可以勾選Unity圖片的Alpha Is Transparency激活。

所以,我們應(yīng)該取消Spine的premultiplied alpha選項(xiàng),并勾選Bleeding選項(xiàng)來(lái)生成普通的圖片(SpineEditorUtilities.cs有自動(dòng)導(dǎo)入腳本,需要修改,否則圖片參數(shù)會(huì)被它重新設(shè)置回去)。

Shader內(nèi),直接用最普通的方式繪制就好了。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

瑕疵依然存在,但是回到了普通不透明圖片的壓縮質(zhì)量水準(zhǔn)。(具體質(zhì)量要看使用的壓縮格式,比如ASTC肯定要比ETC2更好)

——但是,Spine并不能直接用普通的Alpha Blend方式繪制貼圖。

Spine的整個(gè)Shader都是基于Blend One OneMinusSrcAlpha,也就是預(yù)乘混合模式。它要求frag輸出的顏色通道必須是預(yù)乘過(guò)Alpha通道的,所以,如果輸入的圖片是未預(yù)乘的,就要在采樣后乘上透明度,再輸出。

col = tex2D(_MainTex,xxxxx);
col.rgb *= col.a;

倒也簡(jiǎn)單,但為什么不直接將混合模式直接改成普通的Blend SrcAlpha OneMinusSrcAlpha呢?這就是下個(gè)話題的內(nèi)容——

如何用一個(gè)PASS同時(shí)繪制Alpha Blend和Additive物體?

Alpha Blend 對(duì)應(yīng)的是 Blend SrcAlpha OneMinusSrcAlpha,

相當(dāng)于lerp(x.rgb,y.rgb,x.a),也就是result = (x.r, x.g, x.b) * x.a + (y.r, y.g, y.b) * (1 - x.a)

Additive則是result = (x.r, x.g, x.b) *x.a + (y.r, y.g, y.b)

而預(yù)乘混合Blend One OneMinusSrcAlpha是result = (x.r, x.g, x.b) + (y.r, y.g, y.b) * (1 - x.a),由于我們的紋理并不是預(yù)乘過(guò)的,而是在shader內(nèi)相乘,所以是za = x.a,result = (x.r, x.g, x.b) * za + (y.r, y.g, y.b) * (1 - x.a),結(jié)果上和Alpha Blend相同。

但這里,za和x.a其實(shí)是不同的參數(shù),我們可以讓它是不同的值。如果za和x.a始終相等,就是AlphaBlend,如果讓za=x.a,同時(shí)把x.a賦值為0,那么結(jié)果就是result = (x.r, x.g, x.b) *x.a + (y.r, y.g, y.b) * (1 - 0)。

和Additive是相同的。

Spine就是用這種方式同時(shí)顯示AlphaBlend和Additive的圖片的,它的頂點(diǎn)色是預(yù)乘過(guò)的,比如白色50%透明度就是(0.5,0.5,0.5,0.5),而如果是Additive的部分,白色50%透明度就是(0.5,0.5,0.5,0),因?yàn)橥该鞫葹?,所以輸出的x.a永遠(yuǎn)都是0,效果就和Additive相同。

這樣直接乘在顏色值上,然后用Blend One OneMinusSrcAlpha輸出就可以了。

如果并不是將透明度重置為0,而是取一個(gè)中間值,還可以得到Alpha Blend和Additive中間的一個(gè)結(jié)果,在Alpha Blend太暗,Additive太亮的時(shí)候可以考慮(一般特效美術(shù)會(huì)選擇用兩個(gè)不同材質(zhì)的紋理疊加,其實(shí)沒(méi)必要)

如何做Spine的半透顯示?

GrabPass是不可取的,因?yàn)榇嬖谕该魑矬w的半透疊加。所以唯一的方法就是繪制到RT上再顯示。

這時(shí)候就會(huì)遇到同時(shí)繪制Alpha Blend和Additive的問(wèn)題。需要將攝像機(jī)的ClearColor設(shè)置成0,0,0,0(而不是0,0,0,1),Alpha的物體不能有ColorMask,Additive的物體需要ColorMask RGB(或者Alpha值為0)。

而顯示RT時(shí),必須用Blend One OneMinusSrcAlpha才能正確,否則Addtive的部分會(huì)沒(méi)效果。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法  
用SrcAlpha OneMunusSrcAlpha繪制
Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法  
用One OneMunusSrcAlpha繪制

在這種情況下,設(shè)置為半透不能只修改alpha值,而且是要同時(shí)修改全部通道。

Blend One OneMinusSrcAlpha的物體只修改Color的Alpha值,相當(dāng)于在AlphaBlend和Additive的顯示效果之間調(diào)整,其實(shí)還挺便利的。這個(gè)中間的部分其實(shí)很適合用來(lái)模擬科幻場(chǎng)景的空氣投影屏幕,因?yàn)锳lphaBlend太實(shí),Additive又太像光。

而真正的空氣投影屏幕誰(shuí)也沒(méi)見(jiàn)過(guò),畢竟都沒(méi)誕生。

動(dòng)態(tài)立繪應(yīng)當(dāng)啟用Mipmap

很多人對(duì)Mipmap有誤解,認(rèn)為這是一個(gè)優(yōu)化手段,而且是在處理遠(yuǎn)近物體的時(shí)候用的。

Mipmap最初的目的其實(shí)是為了處理紋理走樣問(wèn)題,優(yōu)化只是一個(gè)副產(chǎn)品。

比較著名的示例是這個(gè),又稱(chēng)為摩爾紋。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

在立繪的情況下是這個(gè),也算是紋理鋸齒的一種。

Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法

至于出現(xiàn)的原因?紋理過(guò)濾時(shí),圖像的放大其實(shí)和PS里是類(lèi)似的,也就是普通的2次線性插值,但是縮小時(shí)則完全不同。PS將圖像縮小一倍,目標(biāo)像素是對(duì)應(yīng)的4個(gè)像素的平均值,但是在紋理過(guò)濾的時(shí)候,只會(huì)取的最近的1個(gè)像素的值。

很顯然,這是為了效率考慮。

mipMap則將這4個(gè)像素的平均值預(yù)先儲(chǔ)存了一份,這種情況下就可以直接取值了。其實(shí)效率是差不多的,但只有mipMap的才是正確的。

但在兩個(gè)mipMap層級(jí)中間的時(shí)候,即使使用三向過(guò)濾或者多重采樣過(guò)濾,會(huì)從兩個(gè)mipMap層級(jí)之間插值,依然還是不正確的。因?yàn)椴蓸恿说头直媛实膱D像,還會(huì)導(dǎo)致圖像產(chǎn)生模糊。

也就是在信號(hào)學(xué)所說(shuō)的“在不提高分辨率的情況下,我們只能把信號(hào)中無(wú)法還原的高頻部分拋棄掉,避免出現(xiàn)劇烈的變化,來(lái)實(shí)現(xiàn)所謂的反走樣”,即是,想要反走樣,就必須承擔(dān)一定程度的模糊。想要反走樣又不想模糊,只有一個(gè)辦法,提升分辨率。

出現(xiàn)走樣并不需要3D,只要你的圖片存在兩個(gè)像素被并進(jìn)一個(gè)像素顯示的情況(這通過(guò)縮放也可以達(dá)成),如果你的圖片分辨率高于屏幕分辯率就更是如此。

不過(guò),大部分走樣效果并不明顯,因?yàn)槿搜蹠?huì)自己修正。但是,如果你的物體是運(yùn)動(dòng)的,走樣就會(huì)產(chǎn)生另一種效果“閃爍”,這就非常明顯了。上面的鋸齒其實(shí)也算是一種線段的時(shí)隱時(shí)現(xiàn)。

如果你的圖片是靜態(tài)的,用一點(diǎn)點(diǎn)走樣換取圖片的“清晰”其實(shí)更合算。但是動(dòng)態(tài)立繪,請(qǐng)不要。

當(dāng)然,如果你的分辨率極高,高到人眼無(wú)法分辨,走樣確實(shí)也無(wú)所謂了。

但這樣的話,模糊也同樣無(wú)所謂。

而且別忘了,Mipmap確實(shí)在很多情況下可以提高性能。

到此,關(guān)于“Spine的紋理壓縮和半透顯示的實(shí)現(xiàn)方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

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

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

AI