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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

批量 材质 调整_游戏图形批量渲染及优化:Unity静态合批技术

發(fā)布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 批量 材质 调整_游戏图形批量渲染及优化:Unity静态合批技术 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:枸杞憂天

(本文首發(fā)于公眾號“偶爾學(xué)學(xué)Unity”,文章僅為作者觀點(diǎn),不代表GWB立場)

最近在準(zhǔn)備公司的技術(shù)分享,主題是入門批量渲染,想著反正也總結(jié)了,不如充幾篇博客吧,也算顯得沒有那么半途而廢,一舉兩得了。

所以,這次將分四篇介紹一下與批量渲染有關(guān)的知識:

第一篇的主題是靜態(tài)合批;

第二篇的主題是動態(tài)合批;

第三篇的主題是實例化渲染;

第四篇的主題是優(yōu)化骨骼蒙皮動畫,以及兩種常用的批量渲染方式:烘焙頂點(diǎn)動畫與烘焙骨骼矩陣動畫。

那就開始吧。

批量渲染

批量渲染其實是個老生常談的話題,它的另一個名字叫做“合批”。在日常開發(fā)中,通常說到優(yōu)化、提高幀率時,總是會提到它。

可以簡單的理解為:批量渲染是通過減少CPU向GPU發(fā)送渲染命令(DrawCall)的次數(shù),以及減少GPU切換渲染狀態(tài)的次數(shù),盡量讓GPU一次多做一些事情,來提升邏輯線和渲染線的整體效率。但這是建立在GPU相對空閑,而CPU把更多的時間都耗費(fèi)在渲染命令的提交上時,才有意義。

如果瓶頸在GPU,比如GPU性能偏差,或片段著色器過于復(fù)雜等,那么沒準(zhǔn)適當(dāng)減少批處理,反而能達(dá)到優(yōu)化的效果。

所以要做性能優(yōu)化,還是應(yīng)該先定位瓶頸到底在哪兒,然后再考慮優(yōu)化方案,而不是一股腦的就啪啪啪合批。

當(dāng)然,通常情況下,確實是以CPU出現(xiàn)瓶頸更為常見,所以適當(dāng)?shù)牧私庑┡夸秩镜募挤?#xff0c;是有那么一丟丟必要的。

靜態(tài)合批

靜態(tài)合批是一種聽起來很常用,但在大多數(shù)手游項目里又沒那么常用的合批技術(shù)。

這里,我簡單的將靜態(tài)合批分為預(yù)處理階段的合并,和運(yùn)行階段的批處理。

合并階段

合并時,引擎將符合合批條件的渲染器身上的網(wǎng)格取出,對網(wǎng)格上的頂點(diǎn)進(jìn)行空間變換,變換到合并根節(jié)點(diǎn)的坐標(biāo)系下后,再合并成一個新的網(wǎng)格;這里需要注意的是,新網(wǎng)格是以若干個子網(wǎng)格的形式組合而成的,因為需要記錄每一個合并前網(wǎng)格的索引數(shù)量和起始索引(相對于合并后的新網(wǎng)格)。

空間變換的目的,是為了“固化”頂點(diǎn)緩沖區(qū)和索引緩沖區(qū)內(nèi)的數(shù)據(jù),使其頂點(diǎn)位置等信息都在相同的坐標(biāo)系下。這樣運(yùn)行時如果需要對合并后的對象進(jìn)行空間變換(手動靜態(tài)合批對象的根節(jié)點(diǎn)可被空間變換),則無需修改緩沖區(qū)內(nèi)的頂點(diǎn)屬性,只提供根節(jié)點(diǎn)的變換矩陣即可。

盡管網(wǎng)格不同、材質(zhì)不同,Unity也會將它們的網(wǎng)格進(jìn)行合并

在Unity中,可以通過勾選靜態(tài)批處理標(biāo)記,讓引擎在打包時自動合并;當(dāng)然,也可以在運(yùn)行時調(diào)用合并函數(shù),手動合并。

通過勾選開關(guān)標(biāo)記單位參與靜態(tài)合批

打包時的自動合并會膨脹場景文件,會在一定程度上影響場景的加載時間。

包含靜態(tài)合批的場景體積大了一丟丟

此外,不同平臺對于合并是有頂點(diǎn)和索引數(shù)量限制的,超過此限制則會合并成多個新網(wǎng)格。

批處理階段

運(yùn)行時是否可以合批(Batch)成功,還取決于渲染器材質(zhì)的設(shè)置。

使用不同的材質(zhì),會分為不同的批次

當(dāng)然,如果手動替換過場景中所有Material,也會打斷批次。

運(yùn)行時手動替換所有渲染器的材質(zhì)球

不再有合批發(fā)生

如果偷偷修改了渲染器使用的網(wǎng)格(不再使用合批后的大網(wǎng)格),也會打斷批處理。

替換網(wǎng)格后,也不會再被批處理

除上述之外,還有一些不常用,且不太有用的知識點(diǎn)。

運(yùn)行時動態(tài)加載?

動態(tài)加載并實例化一個帶靜態(tài)標(biāo)記的GameObject到場景中,是不會被當(dāng)做靜態(tài)合批處理的。換言之,靜態(tài)標(biāo)記只被作為是打包時的考慮參數(shù),并不會在運(yùn)行時被引擎處理。如果在場景加載后,希望對手動實例化的單位進(jìn)行靜態(tài)合批,可以使用手動靜態(tài)合批。

合并根節(jié)點(diǎn)的空間變換

自動靜態(tài)合批的根節(jié)點(diǎn)在場景上,因此無法對其進(jìn)行空間變換;而手動靜態(tài)合批,因為根節(jié)點(diǎn)不是場景而是一個游戲?qū)ο?#xff0c;所以可以通過修改根節(jié)點(diǎn)的空間屬性(位置、大小及縮放值),達(dá)到諸如移動整個合批單位的目的。

當(dāng)然,即使修改了合批后對象的空間屬性,頂點(diǎn)和索引緩沖區(qū)里的數(shù)據(jù)也不會被修改,引擎會在渲染前,通過ConstBuffer(UniformBuffer)傳入根節(jié)點(diǎn)的變換矩陣,達(dá)到了整體變換的目的。

Batch ≠ DrawCall

一次靜態(tài)合批,并不表示一定只有一次DrawCall命令的調(diào)用。

合并發(fā)生后,每個參與合批的網(wǎng)格信息(頂點(diǎn)、索引等)就會被最終確定,不再被修改。當(dāng)一個參與合并的單位不顯示時,如被設(shè)置為隱藏或被視椎體剔除,引擎并不會修改頂點(diǎn)緩沖區(qū)和索引緩沖區(qū)的內(nèi)容,而會拆分若干個小的DrawCall來分次渲染。通過調(diào)整每個DrawCall的索引(起始索引、索引個數(shù))來跳過不應(yīng)該被顯示的單位。

通過兩次DrawCall來跳過隱藏的三角形

由于,這些DrallCall之間幾乎沒有渲染狀態(tài)的切換,效率較高,所以引擎也將其統(tǒng)計為一次合批(盡管包含若干個DrawCall)。

隱藏掉部分立方體后,形成了兩次DrawCall

引擎的Statistics窗口、FrameDebugger和Profiler(Renderer)會體現(xiàn)出這種差異

靜態(tài)合批包含了多個材質(zhì)時,引擎在材質(zhì)分組后的處理方式也是相同的,只是不同材質(zhì)在渲染時,都使用了相同的頂點(diǎn)、索引緩沖區(qū)。

與直接使用大網(wǎng)格的不同

靜態(tài)合批與直接使用大網(wǎng)格(是指直接制作而成,非靜態(tài)合并產(chǎn)生的網(wǎng)格)的不同,主要體現(xiàn)在兩方面。

其一,靜態(tài)合批可以主動隱藏部分對象。靜態(tài)合批在運(yùn)行時,由于每個參與合并的對象可以通過起始索引等彼此區(qū)分,因此可以通過上述多次DrawCall的策略,實現(xiàn)隱藏指定的對象;而直接使用大網(wǎng)格,則無法做到這一點(diǎn)。

其二,靜態(tài)合批可以有效參與CPU的視錐剔除。當(dāng)有剔除發(fā)生時,被送進(jìn)渲染管線的頂點(diǎn)數(shù)量就會減少(通過參數(shù)控制),也就意味著被頂點(diǎn)著色器處理的頂點(diǎn)會減少,提升了GPU的效率;而使用大網(wǎng)格渲染時,由于整個網(wǎng)格都會被送進(jìn)渲染管線,因此每一個頂點(diǎn)都需要被頂點(diǎn)著色器處理,如果攝像機(jī)只能照到一點(diǎn)點(diǎn),那么絕大多數(shù)參與計算的頂點(diǎn)最后都會被裁減掉,有一些浪費(fèi)。

大網(wǎng)格不會被視錐體剔除,全部頂點(diǎn)都會被送進(jìn)渲染管線

靜態(tài)合批會被視錐體剔除,只有部分頂點(diǎn)被送進(jìn)渲染管線

靜態(tài)合批下合并后的網(wǎng)格

靜態(tài)合批下,頂點(diǎn)著色器只處理了部分頂點(diǎn)

當(dāng)然,這并不意味著靜態(tài)合批一定就比使用大網(wǎng)格要更好。如果子網(wǎng)格數(shù)量非常多,視錐剔除時CPU的壓力也會增加,所以具體情況具體分析吧~

靜態(tài)合批的利弊

靜態(tài)合批采用了以空間換時間的策略來提升渲染效率。

其優(yōu)勢在于:網(wǎng)格通常在預(yù)處理階段(打包)時合并,運(yùn)行時頂點(diǎn)、索引信息也不會發(fā)生變化,所以無需CPU消耗算力維護(hù);若采用相同的材質(zhì),則以一次渲染命令,便可以同時渲染出多個本來相對獨(dú)立的物體,減少了DrawCall的次數(shù)。

在渲染前,可以先進(jìn)行視錐體剔除,減少了頂點(diǎn)著色器對不可見頂點(diǎn)的處理次數(shù),提高了GPU的效率。

其弊端在于:合批后的網(wǎng)格會常駐內(nèi)存,在有些場景下可能并不適用。比如森林中的每一棵樹的網(wǎng)格都相同,如果對它采用靜態(tài)合批策略,合批后的網(wǎng)格基本等同于:單顆樹網(wǎng)格 x 樹的數(shù)量,這對內(nèi)存的消耗可能就十分巨大了。

極端情況下可能導(dǎo)致內(nèi)存占用過高

總而言之,靜態(tài)合批在解決場景中材質(zhì)基本相同、網(wǎng)格不同、且自始至終都保持靜止的物體上時,很適用。

不出意外的話,下次更新的內(nèi)容應(yīng)該是動態(tài)合批。

下回見。

總結(jié)

以上是生活随笔為你收集整理的批量 材质 调整_游戏图形批量渲染及优化:Unity静态合批技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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