青青青激情视频在线最新-青青青国产在线手机免费观看-青青青国产在线视频-青青青国产在线观看免费网站-青青青国产在线观看免费-青青青国产在线观看

定制高性能GPU粒子系統(tǒng)
佚名
2024-11-14 00:09:17
0

ps玻璃彈孔_玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向

【USparkle專欄】如果你深懷絕技,愛(ài)“搞點(diǎn)研究”,樂(lè)于分享也博采眾長(zhǎng),我們期待你的加入,讓智慧的火花碰撞交織,讓知識(shí)的傳遞生生不息!

這是侑虎科技第1413篇文章,感謝作者 偶爾不帥供稿。歡迎轉(zhuǎn)發(fā)分享,未經(jīng)作者授權(quán)請(qǐng)勿轉(zhuǎn)載。如果您有任何獨(dú)到的見(jiàn)解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群:465082844)

作者主頁(yè):

一、技術(shù)設(shè)計(jì)背景

Unity引擎自帶的粒子系統(tǒng)一直是CPU端計(jì)算的,這里是指粒子系統(tǒng)以下三大步驟都是在CPU計(jì)算。

粒子系統(tǒng)的主要3個(gè)開(kāi)銷大的步驟:

1. 每個(gè)發(fā)射器每幀創(chuàng)建新粒子實(shí)例

2. 每個(gè)粒子實(shí)例每幀更新粒子位置、顏色等狀態(tài)

3. 每個(gè)發(fā)射器的繪制提交與發(fā)射器之間渲染排序

后來(lái)硬件的發(fā)展GPU提升的更快,而實(shí)際項(xiàng)目中常常也是CPU瓶頸居多。所以有了基于ComputeShader與GPUInstance技術(shù)的GPU粒子系統(tǒng)。比如Unreal Engine有CPU和GPU 2套,較新版Unity也有VFX。但是選擇自己寫(xiě)一套主要是這幾個(gè)考量。

玻璃彈孔判斷方向_玻璃彈孔怎么判斷方向_ps玻璃彈孔

基礎(chǔ)功能的面板數(shù)據(jù)

二、單個(gè)復(fù)雜粒子模式

這種模式雖然游戲內(nèi)不太常用,但是性能提升最大,也是開(kāi)發(fā)最簡(jiǎn)單直觀的。而且GitHub已經(jīng)有Demo,我就不重復(fù)寫(xiě)這種模式的代碼了。如果覺(jué)得我這里說(shuō)的不夠詳細(xì),沒(méi)有基礎(chǔ)代碼部分有點(diǎn)暈的同學(xué)可以下載這份很短但完整的源碼。

具體的做法分3個(gè)步驟:

1. 在C#腳本中,每幀對(duì)這個(gè)發(fā)射器計(jì)算這一幀需要?jiǎng)?chuàng)建的粒子數(shù)(根據(jù)粒子系統(tǒng)上每秒多少個(gè)和 Burst參數(shù)),然后需要?jiǎng)?chuàng)建多少個(gè)Dispatch、多少個(gè)線程數(shù),因?yàn)檫@種模式發(fā)射器數(shù)量很少,粒子數(shù)很大,比如全地圖煙霧、全圖落葉等。所以CPU計(jì)算發(fā)射數(shù)的工作量非常少,沒(méi)必要讓GPU計(jì)算。

2. 把這種粒子系統(tǒng)看成粒子數(shù)量是固定的,比如N,這N就是粒子系統(tǒng)里粒子上限參數(shù)。創(chuàng)建長(zhǎng)度為N的StructuredBuffer,存放Particle實(shí)例信息的Struct。因?yàn)槊總€(gè)實(shí)例生命結(jié)束順序不固定,所以需要一個(gè)可用粒子池的AppendBuffer來(lái)記錄Particle數(shù)組里哪些Index粒子可被拿來(lái)復(fù)用。

3. 每幀對(duì)所有粒子實(shí)例更新,每個(gè)ComputeShader線程處理一個(gè)粒子實(shí)例。所以不管當(dāng)前多少個(gè)粒子在渲染都是按N來(lái)做的。這種粒子一般都是循環(huán)N,基本就是要渲染的全部,只要設(shè)置合理,其實(shí)并不會(huì)浪費(fèi)不可見(jiàn)粒子的空循環(huán),比再用Buffer管理有效粒子,渲染時(shí)再跳轉(zhuǎn)反而性能更好。

部分關(guān)鍵代碼:

玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向_ps玻璃彈孔

Buff內(nèi)粒子實(shí)例數(shù)據(jù)

粒子數(shù)據(jù)與可用粒子對(duì)象池索引變量

這里需要注意:dead與alive其實(shí)對(duì)于C#那邊同一份Buffer數(shù)據(jù)。只是在創(chuàng)建粒子的Kernel里消費(fèi),在Init與Update的Kernel里Append,因?yàn)樗劳龌虺跏蓟家蚜W釉O(shè)置為可用,就是把Index還給Buffer。

玻璃彈孔判斷方向_ps玻璃彈孔_玻璃彈孔怎么判斷方向

創(chuàng)建粒子是消耗可用的粒子Index

ps玻璃彈孔_玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向

更新時(shí),如果生命到期就把粒子的Index還給可用Buffer

渲染的時(shí)候,數(shù)量邏輯一樣按粒子系統(tǒng)的設(shè)置maxCount作為InstanceCount。其中不可見(jiàn)的粒子用col=pInst.alive*pInst.color,實(shí)現(xiàn)隱藏。這種模式絕大部分時(shí)候繪制的粒子數(shù)量就接近maxCount,所以基本都是alive=true的,很少空計(jì)算。

以下是測(cè)試結(jié)果渲染20w個(gè)粒子,這種性能提升是巨大的。Unity的CPU方案107幀 VS GPU實(shí)現(xiàn)方案1661幀。

顏色不同是因?yàn)椋珼emo的作者在對(duì)顏色隨生命變化的漸變圖轉(zhuǎn)圖形時(shí),沒(méi)考慮用線性空間導(dǎo)致的,不影響性能對(duì)比。

ps玻璃彈孔_玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向

單個(gè)復(fù)雜粒子CPU/GPU方案幀數(shù)對(duì)比

左邊是抓幀證明渲染的粒子數(shù)量一樣

三、多發(fā)射器的簡(jiǎn)單粒子

這個(gè)模式才是我真正為項(xiàng)目開(kāi)發(fā)的模式,也是更能寫(xiě)出性能大收益的模式,老老實(shí)實(shí)的寫(xiě)很容易負(fù)優(yōu)化。這是因?yàn)镚PU中的半透明與CPU中的半透明對(duì)象很難一起高性能排序,通用引擎為了通用與絕對(duì)正確,據(jù)我粗略了解,這個(gè)問(wèn)題是無(wú)解的(高性能的解),后面會(huì)講如何定制優(yōu)化,先看性能對(duì)比。

單獨(dú)200個(gè)子彈碰撞特效,每個(gè)有6個(gè)發(fā)射器,所以一共1200粒子反射器,但來(lái)回切換激活 同時(shí)只顯示50%左右(后面按每幀600個(gè)粒子更新來(lái)算)。Unity CPU版是373FPS,本方案是2461FPS。如果用上個(gè)方案的那個(gè)GitHub Demo之間做這種,會(huì)發(fā)現(xiàn)只有100多幀,負(fù)優(yōu)化。所以我沒(méi)有拿那個(gè)源碼用,而是自己重新設(shè)計(jì)了一套符合具體項(xiàng)目的方案。

玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向_ps玻璃彈孔

很多發(fā)射器實(shí)例的模式下

性能對(duì)比:Unity CPU粒子(上)

vs 本方案GPU粒子(下)

這是因?yàn)閱蝹€(gè)復(fù)雜粒子模式是每個(gè)粒子發(fā)射器都創(chuàng)建一個(gè)含有粒子數(shù)據(jù)的Buff,每幀通過(guò)Dispatch ComputeShader更新這些粒子,也就是說(shuō),這樣需要600次Dispatch,性能自然就差了。

所以第一步改進(jìn)就是申請(qǐng)一個(gè)公用的大Buff來(lái)存放當(dāng)前激活的所有發(fā)射器的粒子數(shù)據(jù)。對(duì)于這種數(shù)據(jù)組織一般有2種模式:一種是間接尋址,一種是每個(gè)粒子發(fā)射器定長(zhǎng)數(shù)組占用,然后通過(guò)Offset獲取自己在Buffer內(nèi)的數(shù)據(jù)。

這里采用第二種,每種發(fā)射器最多同時(shí)存在32個(gè)粒子實(shí)例,這樣可以滿足大部分戰(zhàn)斗中反復(fù)出現(xiàn)的大量及時(shí)性特效。但是我們上面說(shuō)Particles是根據(jù)粒子創(chuàng)建死亡維護(hù)的對(duì)象池,數(shù)據(jù)是無(wú)序的。當(dāng)時(shí)是同一個(gè)粒子發(fā)射器,一次DrawIndirect,所以不需要在意順序。但現(xiàn)在這個(gè)數(shù)據(jù)里有不同的發(fā)射器創(chuàng)建的粒子,渲染時(shí)也需要訪問(wèn)不同的Index來(lái)獲取對(duì)應(yīng)數(shù)據(jù)。所以需要一個(gè)RWStructuredBuffer particlesIndexer;來(lái)記錄每個(gè)發(fā)射器,包含的粒子在Particles數(shù)組中的Index。每個(gè)發(fā)射器占32位元素,同樣渲染的時(shí)候,需要用另一個(gè)RWStructuredBuffer emitterCounter;,這個(gè)變量就是用在 DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, Bounds bounds, ComputeBuffer bufferWithArgs, int argsOffset); 這個(gè)API里的bufferWithArgs,配合后面argsOffset就能實(shí)現(xiàn)每個(gè)發(fā)射器不同的偏移了。

更新函數(shù)中,是這樣把當(dāng)前幀需要渲染的活著的粒子寫(xiě)入這2個(gè)Buffer的。

玻璃彈孔判斷方向_玻璃彈孔怎么判斷方向_ps玻璃彈孔

這樣雖然每幀對(duì)粒子的Update在一次Dispatch后就執(zhí)行完了,但渲染的時(shí)候,每個(gè)發(fā)射器單獨(dú)執(zhí)行DrawCall還是會(huì)性能很差。從Nsight工具可以看到非常恐怖的切換Shader次數(shù),時(shí)間很快是因?yàn)槲沂?080顯卡,在普通顯卡中這個(gè)性能是不具備現(xiàn)實(shí)可用性的。

玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向_ps玻璃彈孔

每個(gè)粒子發(fā)射器一次DrawCall的GPU切換情況

四、半透明排序與合批渲染

這是整個(gè)技術(shù)的關(guān)鍵所在也是最大的矛盾點(diǎn),目前的DrawIndirect API每次調(diào)用都只能傳一個(gè)AABB,引擎會(huì)根據(jù)這個(gè)AABB中心參與場(chǎng)景里其他對(duì)象進(jìn)行排序,所以一次DrawIndirect繪制的所有粒子擁有同一個(gè)順序,要么全部在某對(duì)象前,要么全部在某對(duì)象后渲染。現(xiàn)在每個(gè)粒子發(fā)射器單獨(dú)一個(gè)DrawCall的情況下排序正常了(和Unity自帶CPU粒子一樣,逐發(fā)射器排序正常,不考慮多個(gè)發(fā)射器之間逐粒子排序),但性能不行。

如果所有同材質(zhì)發(fā)射器合并成一個(gè)DrawCall,那么排序又會(huì)不正常,因?yàn)樗鼈冎虚g出現(xiàn)場(chǎng)景的半透明對(duì)象無(wú)法穿插到這個(gè)DrawCall里。這也是為什么Unity的GPUInstance文章都是不拿半透明做例子,因?yàn)镺paque的排序不正確不影響畫(huà)面效果,有Depth保證最終順序。透明材質(zhì)是沒(méi)有寫(xiě)Depth的,除非用了深度剝離技術(shù)。但這說(shuō)遠(yuǎn)了,一般不會(huì)這樣做的,所以如何合批是重點(diǎn)。

先看下Unity本身是如何合批粒子的,經(jīng)過(guò)簡(jiǎn)單測(cè)試就能發(fā)現(xiàn),如果ab是相同的粒子發(fā)射器的不同實(shí)例,c是不同的粒子反射器,ab距離靠近,而c在ab前或在ab后,那么只有2個(gè)DrawCall;如果c在ab中間就會(huì)有3個(gè)DrawCall。所以引擎是排序后才把相鄰的又相同的反射器合批渲染。但我們渲染數(shù)據(jù)是在GPU,如果讓CPU排序后要合批,則需要搬運(yùn)Buffer內(nèi)數(shù)據(jù)后合并到一起,很復(fù)雜且要改引擎。如果在GPU內(nèi)排序更不可能,GPU內(nèi)只能粒子自己排序,無(wú)法與場(chǎng)景上對(duì)象排序,這些對(duì)象都在CPU。所以通用引擎很難解決這個(gè)問(wèn)題。

但做定制開(kāi)發(fā)就輕松多了。首先觀察下這些項(xiàng)目中的特效,同一種特效總是出現(xiàn)在世界空間位置相機(jī)的地方,比如一個(gè)人開(kāi)槍的特效總是在他槍口附近,而子彈的碰撞特效又總是在前方某個(gè)位置,不同的玩家是不同的,所以只要用玩家ID+粒子發(fā)射器Prefab種類做Key 來(lái)分組,Key相同的一次性渲染就可以了。但這個(gè)性能很高,需要犧牲精確度,比如同一個(gè)人在玻璃后開(kāi)幾槍,再跑玻璃前面開(kāi)幾槍,那么先創(chuàng)建出的玻璃后的粒子也會(huì)一起渲染到玻璃上面。但是這問(wèn)題不大,因?yàn)檫@些特效都是0.5秒之內(nèi)就消失的,不會(huì)長(zhǎng)期停留在跑動(dòng)和下次開(kāi)槍時(shí),但墻上的彈孔是個(gè)特例他們會(huì)停留30秒,所以這個(gè)方案不好。

另一個(gè)更好的方法是根據(jù)世界空間把1立方米內(nèi)的相同粒子發(fā)射器Prefab的所有粒子做一次Draw,因?yàn)槲恢煤芸拷运鼈儼赐粋€(gè)位置參與排序基本是正確的,比較簡(jiǎn)單的是用long類型把這些信息計(jì)算到一起且不重復(fù)。假設(shè)這里場(chǎng)景范圍是正負(fù)5000米,全部合批發(fā)射器用這個(gè)管理 Dictionary activeEmitterTypes;。

玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向_ps玻璃彈孔

根據(jù)位置與發(fā)射器類型計(jì)算合批渲染的編號(hào)

ps玻璃彈孔_玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向

分組發(fā)射器數(shù)據(jù)結(jié)構(gòu)

最后介紹該方案的主要數(shù)據(jù)。因?yàn)楦挠眠@種合批,這里有和上面修改的地方。

玻璃彈孔怎么判斷方向_ps玻璃彈孔_玻璃彈孔判斷方向

按類型與空間合批渲染的更新方式

玻璃彈孔怎么判斷方向_玻璃彈孔判斷方向_ps玻璃彈孔

該方案的主要數(shù)據(jù)

最后看下最終落地效果,從原來(lái)開(kāi)槍掉18幀變成只掉5幀,至此優(yōu)化幾輪的開(kāi)槍降幀問(wèn)題終于有點(diǎn)穩(wěn)住了,之前是根本不能與CSGO相比,他們優(yōu)化的太好了。

ps玻璃彈孔_玻璃彈孔判斷方向_玻璃彈孔怎么判斷方向

最終落地項(xiàng)目

連發(fā)35(常見(jiàn)彈夾)后降幀對(duì)比

五、GPU的優(yōu)化

這個(gè)GPU粒子主要功能是優(yōu)化CPU瓶頸,關(guān)于GPU的性能優(yōu)化順便提下,開(kāi)火會(huì)有大量重疊的多層的大屏幕面積的火焰、煙霧,導(dǎo)致Overdraw問(wèn)題非常大,觀察CSGO與COD有幾個(gè)簡(jiǎn)單優(yōu)化技巧:

文末,再次感謝jackie 偶爾不帥的分享,作者主頁(yè):,如果您有任何獨(dú)到的見(jiàn)解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群:465082844)

近期精彩回顧

ps玻璃彈孔_玻璃彈孔判斷方向_玻璃彈孔怎么判斷方向

相關(guān)內(nèi)容

定制高性能GPU粒子系統(tǒng)
用自己定制優(yōu)化的特殊排序提高GPU粒子系統(tǒng)性能
2024-11-14 00:09:17

熱門資訊

票房破3000萬(wàn),看完《焚城》... 票房破3000萬(wàn),看完《焚城》,我想說(shuō):劉德華這片拍出了港片良心,焚城,范偉,票房,港片,劉德華,莫...
業(yè)界最美混血美少女,長(zhǎng)相清純卻... 今天要給大家介紹的這位女神,有著日美混血的美少女—西田卡莉娜!
盤(pán)點(diǎn)《七龍珠》劇場(chǎng)版20部,你... 今天小白為大家整理《七龍珠》劇場(chǎng)版,沒(méi)想到總計(jì)有20部哦,龍珠迷們,你們又看過(guò)幾部呢?接下來(lái)我們來(lái)盤(pán)...
水龍頭單孔和雙孔區(qū)別 單孔和雙... 相信大家對(duì)水龍頭都不陌生吧!在日常生活中,水龍頭是特別常見(jiàn)的一種用具。我們大多數(shù)人都了解水龍頭嗎?知...
包青天系列電視劇觀看順序指南:... 包青天幾部的先后順序?①1、《包公出巡》是王枚,金鰲勛執(zhí)導(dǎo)的古裝傳奇劇。2、《包公奇案》,以“情花劫...
因果報(bào)應(yīng):2024年度印度懸疑... 在印度電影的璀璨星空中,懸疑片以其獨(dú)特的魅力和深刻的社會(huì)意義,一直占據(jù)著不可動(dòng)搖的地位。最近,一部名...
《春花焰》大結(jié)局:惡心的小說(shuō)改... 從9月開(kāi)始,古裝劇連臺(tái)好戲,有任嘉倫和李蘭迪主演的《流水迢迢》,李沁和曾舜晞主演的《七夜雪》,劉學(xué)義...
動(dòng)漫七大粉色系美少女,最后一個(gè)... 粉色系是少女心的代表色,象征著可愛(ài)、萌、單純。細(xì)數(shù)動(dòng)漫中擁有粉色頭發(fā)的美少女們,她們不世故、單純而善...
白夜破曉續(xù)作強(qiáng)勢(shì)回歸,原班人馬... 七年磨一劍,白夜系列再續(xù)經(jīng)典時(shí)隔七年,備受期待的《白夜追兇》續(xù)作——《白夜破曉》終于在今日(11月2...
諜戰(zhàn)劇《深潛》央八首播,看完3... 38集諜戰(zhàn)新劇《深潛》!成毅、穎兒、劉歡、侯夢(mèng)瑤、張?zhí)礻?yáng)、何中華、王勁松主演。目前,《深淺》在央視播...
主站蜘蛛池模板: 丝袜护士强制脚足取精 | 日韩欧美在线视频一区二区 | 99视频免费| 国产探花在线视频 | 亚洲成aⅴ人片在线 | 精品在线观看一区 | 欧美特黄特色aaa大片免费看 | 娇妻被老外疯狂调教 | 和直男装修工在工地啪 | 日韩在线二区全免费 | 亚洲精品AV无码永久无码 | 99视频免费在线观看 | 亚洲精品色婷婷在线影院麻豆 | 欧美区视频 | 欧美国产日韩在线播放 | 青草网址| 亚洲四虎影院 | 2019国产精品 | 色倩网站 | 成人福利在线播放 | 色综久久天天综合绕视看 | a级毛片毛片免费观看永久 a级黄色片免费 | 99热精品在线播放 | 亚洲精品欧洲久久婷婷99 | 黄色大片网 | 97精品国产自在现线免费 | 欧美贵妇videos办公室360 | 亚洲精品私拍国产福利在线 | 成人综合久久综合 | 亚飞与亚基国语1080p在线观看 | 操熟美女又肥又嫩的骚屁股 | 欧美操大逼视频 | 青青久在线视频免费观看 | 逼毛片| 九九精品国产兔费观看久久 | 四虎影院免费在线 | 欧美日本一道高清免费3区 欧美人做人爱a全程免费 | 校草让我脱了内裤给全班看 | 人人澡 人人澡碰人人看软件 | 艹b小说 | 欧美黑人性猛交╳xx╳动态图 |