日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

echart 实例显示位置_技术分享:如何在Unity中使用实例化渲染?

發(fā)布時(shí)間:2025/3/21 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 echart 实例显示位置_技术分享:如何在Unity中使用实例化渲染? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

編者按?在日常開發(fā)中,通常說到優(yōu)化、提高幀率時(shí),總是會(huì)提到批量渲染。之前簡單總結(jié)了靜態(tài)合批(點(diǎn)此查看全文)以及動(dòng)態(tài)合批(點(diǎn)此查看全文),這次作者將和大家聊聊實(shí)例化渲染。

作者:枸杞憂天

(本文內(nèi)容由公眾號“偶爾學(xué)學(xué)Unity”提供,轉(zhuǎn)載請征得同意。文章僅為作者觀點(diǎn),不代表GWB立場)

當(dāng)我們想要呈現(xiàn)這樣的場景:一片茂密的森林、廣闊的草原或崎嶇的山路時(shí),會(huì)發(fā)現(xiàn)在這些場景中存在大量重復(fù)性元素:樹木、草和巖石。

仙境怕是也不過如此吧它們都使用了相同的模型,或者模型的種類很少,比如:樹可能只有幾種;但為了做出差異化,它們的顏色略有不同,高低參差不齊,當(dāng)然位置也各不相同。使用靜態(tài)合批來處理它們(假設(shè)它們都沒有動(dòng)畫),是不合適的。因?yàn)閿?shù)量太多(林子大了,多少樹都有),所以合并后的網(wǎng)格體積可能非常大,這會(huì)引起內(nèi)存的增加;而且,這個(gè)合并后的網(wǎng)格還是由大量重復(fù)網(wǎng)格組成的,不劃算。使用動(dòng)態(tài)合批來處理他們,雖然不會(huì)“合并”網(wǎng)格,但是仍然需要在渲染前遍歷所有頂點(diǎn),進(jìn)行空間變換的操作;雖然單顆樹、石頭的頂點(diǎn)數(shù)量可能不多,但由于數(shù)量很多,所以也會(huì)在一定程度上增加CPU性能的開銷,沒必要。那么,對于場景中這些模型重復(fù)、數(shù)量多的渲染需求,有沒有適合的批處理策略呢?有吧,實(shí)例化渲染就是為了解決這樣的問題。實(shí)例化渲染,是通過調(diào)用“特殊”的渲染接口,由GPU完成的“批處理”。它與傳統(tǒng)的渲染方式相比,最大的差別在于:調(diào)用渲染命令時(shí)需要告知GPU這次渲染的次數(shù)(繪制N個(gè))。當(dāng)GPU接到這個(gè)命令時(shí),就會(huì)連續(xù)繪制N個(gè)物體到我們的屏幕上,其效率遠(yuǎn)高于連續(xù)調(diào)用N次傳統(tǒng)渲染命令的和(一次繪制一個(gè))。舉個(gè)例子,假設(shè)希望在屏幕上繪制出兩個(gè)顏色、位置均不同的箱子。如果使用傳統(tǒng)的渲染,則需要調(diào)用兩次渲染命令(DrawCall = 2),分別為:畫一個(gè)紅箱子 和 畫一個(gè)綠箱子。兩個(gè)顏色、位置各異的箱子如果使用實(shí)例化渲染,則只需要調(diào)用一次渲染命令(DrawCall = 1),并且附帶一個(gè)參數(shù)2(表示繪制兩個(gè))即可。當(dāng)然,如果只是這樣,那GPU就會(huì)把兩個(gè)箱子畫在相同的位置上。所以我們還需要告訴GPU兩個(gè)箱子各自的位置(其實(shí)是轉(zhuǎn)換矩陣)以及顏色。這個(gè)位置和顏色我們會(huì)按照數(shù)組的方式傳遞給GPU,大概這個(gè)樣子吧:分別傳遞保存位置和顏色的數(shù)組那接下來GPU在進(jìn)行渲染時(shí),就會(huì)在渲染每一個(gè)箱子的時(shí)候,根據(jù)當(dāng)前箱子的索引(第幾個(gè)),拿到正確的屬性(位置、顏色)來進(jìn)行繪制了。一個(gè)簡單的實(shí)例化渲染流程我們通過一個(gè)簡單的場景,來看一下Unity為實(shí)例化渲染做了什么。實(shí)例化渲染兩個(gè)彩色箱子顏色屬性通過MaterialPropertyBlock傳入通過GPA觀察Unity做了什么。GPA中的VertexBuffer和IndexBuffer中的信息注:Unity默認(rèn)Cube網(wǎng)格,包含24個(gè)頂點(diǎn)和36個(gè)索引。
  • 頂點(diǎn)緩沖區(qū)Size = (Position(float3)

    + Normal(float3)

    + Tangent(float4)

    + TexCoord(float2)

    + TexCoord1(float2)) x 24 = 1344Byte

  • 索引緩沖區(qū)Size = Index(ushort) x 36 = 72Byte

可見,頂點(diǎn)、索引緩沖區(qū)內(nèi),確實(shí)只有一個(gè)網(wǎng)格的數(shù)據(jù)。那么GPU如何判斷每個(gè)Cube的繪制位置,及其顏色呢?結(jié)合引擎為Dx平臺(tái)生成的shader(我的測試環(huán)境使用的是Pc),可以很容易找到對應(yīng)的數(shù)據(jù)。轉(zhuǎn)換矩陣及顏色被分別填入Constant Buffer中Constant Buffer中的矩陣(Dx為行向量)Constant Buffer中的屬性(顏色)可見,渲染時(shí)GPU可以通過當(dāng)前實(shí)例化單位的索引,從Buffer中獲取到對應(yīng)的屬性,完成正確的繪制。當(dāng)然,相比于上述無用的知識點(diǎn),如何在Unity中使用實(shí)例化渲染可能更為重要。在Unity中可以通過自動(dòng)或手動(dòng)的方式,啟用實(shí)例化渲染。自動(dòng)啟用實(shí)例化渲染使用支持實(shí)例化渲染的Shader,并勾選材質(zhì)球上的啟用開關(guān),Unity便會(huì)對滿足條件的物體,自動(dòng)開啟實(shí)例化渲染。有這個(gè)選項(xiàng)即表示該Shader支持實(shí)例化渲染自定義Shader如果你希望自己的Shader也支持實(shí)例化渲染,應(yīng)重點(diǎn)注意以下內(nèi)容:#pragma multi_compile_instancing啟用實(shí)例化渲染(材質(zhì)球上將出現(xiàn)啟用實(shí)例化的勾選框);UNITY_VERTEX_INPUT_INSTANCE_ID在a2v及v2f的結(jié)構(gòu)中定義實(shí)例化索引下標(biāo)(SV_InstanceID ),也就是當(dāng)前渲染單位的索引,用于從Constant Buffer中提取正確的屬性(做顯示差異化用);UNITY_INSTANCING_BUFFER_START ~ END在這個(gè)起止區(qū)域內(nèi)定義屬性,才能在著色器中正確的根據(jù)索引提取出當(dāng)前渲染單位所對應(yīng)的屬性;UNITY_SETUP_INSTANCE_ID定義在著色器的起始位置,使頂點(diǎn)著色器(或片段著色器)可以正確的訪問到實(shí)例化單位的索引;UNITY_ACCESS_INSTANCED_PROP根據(jù)索引訪問到這個(gè)單位對應(yīng)的屬性,如上面例子中每個(gè)箱子的顏色屬性。這里只是簡述一些相對重要的內(nèi)容(湊些字?jǐn)?shù)),官方文檔中有更詳細(xì)內(nèi)容,建議優(yōu)先了解。手動(dòng)實(shí)例化渲染使用 ?Graphics.DrawMeshInstanced 和 Graphics.DrawMeshInstancedIndirect 來手動(dòng)執(zhí)行 GPU 實(shí)例化,詳見官方文檔中的解釋,這里就不再贅述了。并非所有設(shè)備都可以使用實(shí)例化渲染。在Unity官方文檔中,列舉了各平臺(tái)支持實(shí)例化渲染的最低要求。官方文檔中對支持實(shí)例化渲染的最低API要求當(dāng)然,我們也可以通過引擎中SystemInfo.supportsInstancing屬性來判斷環(huán)境是否支持實(shí)例化渲染。那支持實(shí)例化渲染的機(jī)器占比大概是多少呢?由于國內(nèi)大多數(shù)游戲公司都是以手游項(xiàng)目糊口。所以開發(fā)者可能會(huì)更多關(guān)注其在安卓平臺(tái)上的情況。根據(jù)Android開發(fā)者的官方數(shù)據(jù)顯示,截至2020年8月30日,約88%的活躍安卓設(shè)備,都已經(jīng)支持實(shí)例化渲染,所以基本上可以放心使用。android開發(fā)者官網(wǎng)發(fā)布的活躍設(shè)備OpenGL ES版本占比信息靜、動(dòng)態(tài)合批實(shí)質(zhì)上是將可以合批的對象真正的合并成一個(gè)大物體后,再通知GPU進(jìn)行渲染,也就是其頂點(diǎn)索引緩沖區(qū)中必須包含全部參與合批對象的頂點(diǎn)信息;因此,可以認(rèn)為是CPU完成的批處理。實(shí)例化渲染是對網(wǎng)格信息的重復(fù)利用,無論最終要渲染出幾個(gè)單位,其頂點(diǎn)和索引緩沖區(qū)內(nèi)都只有一份數(shù)據(jù),可以認(rèn)為是GPU完成的批處理。其實(shí)這么總結(jié)也有點(diǎn)問題,本質(zhì)上講:動(dòng)、靜態(tài)合批解決的是合批問題,也就是先有大量存在的單位,再通過一些手段合并成為批次;而實(shí)例化渲染其實(shí)是個(gè)復(fù)制的事兒,是從少量復(fù)制為大量,只是利用了它“可以通過傳入屬性實(shí)現(xiàn)差異化”的特點(diǎn),在某些條件下達(dá)到了與合批相同的效果。無論是靜態(tài)合批、動(dòng)態(tài)合批或?qū)嵗秩?#xff0c;本質(zhì)上并無孰優(yōu)孰劣,它們都只是提高渲染效率的解決方案,也都有自己適合的場景或擅長解決的問題。個(gè)人以為:如果你的場景中存在多數(shù)靜止的、使用了不同網(wǎng)格、相同材質(zhì)的物體,特別是當(dāng)你的相機(jī)通常只能照到一部分物體時(shí)(如第一視角),可以優(yōu)先嘗試下靜態(tài)合批,通過犧牲一些內(nèi)存來提升渲染效率;針對那些運(yùn)動(dòng)的、網(wǎng)格頂點(diǎn)數(shù)很少、材質(zhì)相同的物體,比如飛行的各種箭矢、炮彈等,使用動(dòng)態(tài)合批,通過增加一些CPU處理頂點(diǎn)的性能開銷,來提升渲染效率,也許是不錯(cuò)的選擇;如果有大量模型相同、材質(zhì)相同、或盡管表現(xiàn)上有一些不同,但仍然可以通過屬性來實(shí)現(xiàn)這些差異化的物體時(shí),啟用實(shí)例化渲染通常可以在很大程度上提升渲染效率。????????????按計(jì)劃下次更新的內(nèi)容應(yīng)該是“優(yōu)化骨骼蒙皮動(dòng)畫,以及兩種常用的批量渲染方式”,但覺得內(nèi)容有點(diǎn)多,所以將其分為兩個(gè)部分;因此,下次更新的內(nèi)容變?yōu)椤皟?yōu)化骨骼蒙皮動(dòng)畫”,而“兩種常用的骨骼蒙皮動(dòng)畫單位的批量渲染方式”,將作為本系列的最后一次更新內(nèi)容。

總結(jié)

以上是生活随笔為你收集整理的echart 实例显示位置_技术分享:如何在Unity中使用实例化渲染?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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