unity 半透明混合問題 Unity批次合併渲染

2021-10-13 22:40:57 字數 3539 閱讀 9359

為了減少cpu與gpu交流的成本,減少drawcall的數量,優化渲染,unity提供了合併批次進行渲染的方式,其支援動態批次合併靜態批次合併gpu例項化三種合併批次方式,這些合併批次的方式是通過操作頂點緩衝區物件(vbo)索引緩衝區物件(ebo)等資料來進行合併處理的。相較於手動合併,unity內建的批處理方法最大的優點是每乙個物體仍然支援單獨剔除。由於在unity渲染優化過程中合併批次渲染非常重要,我們今天來**一下這三種批次渲染方法的原理與異同
頂點緩衝區物件(vbo):主要用於儲存頂點以及頂點附帶的各種屬性資訊,比如頂點位置、法線、顏色、uv等

頂點陣列物件(vao):規定vbo中資料的格式。比如多少空間儲存頂點座標,多少空間儲存頂點法線等等

索引緩衝區物件(ebo):負責快取vbo中頂點的索引,用來解決頂點資料重複使用的問題,避免頂點資料被重複儲存。舉個例子,繪製乙個長方形需要四個頂點、兩個三角形,在沒有ebo的情況下需要在vbo中儲存6個頂點的資料(其中兩個是重複的)。存在ebo時,vbo中儲存四個頂點的資料,通過ebo中的索引順序重複呼叫vbo中相應頂點資料繪製三角形

你好,三角形 - learnopengl cn​learnopengl-cn.github.io

只有使用了相同材質的物體才能夠實現批處理。如果兩個不同的物體,使用的兩個材質,只是紋理上的差別,那就把他們的紋理合併到一起,這樣就可以使用同乙個材質。指令碼中使用render.material屬性時,會重新生成乙個原來材質的拷貝,所以用render.sharedmaterial可以保持材質的一致性(但是使用同乙個材質的物體,都會被改變)。關於陰影,只要材質中使用的是相同的shadow pass,就可以實現批處理,即便他們不是同乙個材質

原理:將所有靜態合併批次中物體的頂點資訊合併成乙個大的vbo。不合併ebo,vbo直接提交給gpu,但ebo部分僅提供需要渲染的部分,避免執行不必要的渲染。在player setting中勾選了opeimized mesh data以後,unity在構建vbo時,會移除那些在所有shader變體中都沒有被用到的頂點的屬性。unity通過一些特殊的關鍵字檢查來實現這個操作,比如如果沒有包含lightmap_on,該批處理的頂點輸入中就會刪除lightmap uvs

實現:靜態批次處理主要針對場景中靜止的物體,將這些物體設定為batching static,引擎便會自動將其新增到靜態合批的佇列中

補充:靜態批處理,並不是所有的模型都合併到同乙個mesh裡,合併的時候仍然受限於mesh的頂點數要求,在大多數平台上,批處理限制是64k個頂點和64k個索引(opengles上48k個索引,macos上32k個索引)。如果幾個模型的頂點總數超過了這個限制,就會被拆分成多個draw call,但是這樣的拆分,並不會造成setpass call的變化,因為渲染狀態沒有變化,所以這些被分開的渲染批次仍然執行的很快

原理:執行時將符合要求的物體動態地組成vbo並提交。因為組建vbo是有開銷的(需要對頂點座標和uv等進行一定的空間變換),所以對動態合批的物體的頂點數有乙個限制。這些限制是為了控制vbo大小而設定的

缺點:cpu開銷增加

實現:unity內部自動實現

限制:處理對頂點的限制是頂點數900以下(unity內建的球體就因頂點數過多而不能被動態批處理);如果著色器使用了座標、法線和單個uv資訊,這個限制就會降到300;如果著色器使用了座標、法線、兩個uv,以及切線空間座標資訊,則這個數值就會降到180(unity 2017.2版本)。

補充:當物體的縮放比為負時(映象),不能進行批處理。

​ 使用光照貼圖的物件,光照貼圖的相關引數一致才能進行批處理

​ 多pass的材質,如果兩個物件使用的pass不同,也會中斷批處理

​ 動態批處理會在每幀將模型的頂點轉換到世界座標系,這部分計算發生在cpu,部分情況需要權衡這些消耗

​ 對於每個相容的渲染器型別,unity將所有可批處理的內容構建到乙個大的頂點快取中

​ renderer元件為批處理設定材質狀態

​ unity將頂點快取繫結到圖形裝置

​ 對於批處理中的每個renderer,unity會將偏移更新到頂點快取中,然後提交乙個新的繪製呼叫

​ 在計算渲染成本時,渲染元件最慢的部分是材質狀態的設定。相比之下,將不同偏移量的draw call提交到共享頂點快取會非常快。這種方法更像是unity在使用靜態批處理時如何提交draw call

能夠批處理的包括:mesh renderers,trail renderers,line renderers,particle systems,sprite renderers。其他的如skinned meshes,cloth等渲染元件並能批處理

半透明物體在渲染時,使用的是從遠到近的順序,所以批處理對它的支援不如opaque

手動合併(通過建模軟體,或者mesh.combinemeshes方法)臨近的物體,有時候也是不錯的優化方式

原理:只提交乙個模型的vbo資訊,但關於多個同種模型的不同資訊(位置、大小和顏色等簡單資料結構的資訊)另外組成per instance attribute(pia)快取並提供給gpu。當然,這個快取是不能儲存貼圖資訊的。gpu instancing技術,在模型的批處理上相當有用,比如地形上大量的草,樹等,當然對於這部分可以直接靜態合批處理成一整個網格,但是頂點數目又會有65000個的限制。這時候gpu instancing就有一定的優勢(關鍵還支援材質球上屬性的差異性,比如官網的例子中就提供了顏色值的差異性)

缺點:gpu instancing可以有效地減少cpu的佔用率,降低顯示驅動的cpu開銷,但會在一定程度上增加gpu端的負擔。同時,由於gpu例項化的原理,在同一批次處理的物體必須擁有相同的網格(動態合批沒有這個限制)

補充:gpu例項化的簡單應用:

最後需要注意在unity5.6版本後,材質選項中必須勾選enable gpu instancing選項,否則該材質無法參與gpu例項化

考慮到綜合負擔與消耗,unity的合併批次優先順序是靜態合批 > gpu例項 > 動態合批

可以通過profiler的render部分檢視三種批次合併方法所起到的具體作用

很明顯此場景並未進行優化,靜態批處理與gpu例項化的操作幾乎沒有

qt opengl 混合實現半透明

在二維繪圖裡面的半透明很簡單,把alpha通道的值不設定為1或者255就能看見後面的物體 後面物體的清晰度根據設定值的大小來決定。而在opengl中要實現半透明效果也很簡單,但相比二維繪圖還是要麻煩一些了。其方法為啟用gl blend混合功能,設定混合因子 這樣opengl就會用混合因子將前 後兩個...

Unity 中的半透明

首先說unity中的渲染順序,在unity中改變渲染順序的方式有四層,第一層為camera的depth,第二層為sorting layers,canvas可直接在面板中調節,其他的可能需要在指令碼中設定,第三層為shader中的渲染佇列,第四層為pass pass的順序在不同情況下有差別 再說半透明...

unity 半透明與不透明物件渲染順序

不透明物件shader片段 subshader cull off lighting off zwrite off fog offset 1,1 blend srcalpha oneminussrcalpha pass 半透明物件shader片段 subshader cull off lighting...