在咱們的遊戲場景中,有一個場景物件是由三個半透明面片組成的,他們三個使用的是同一個材質球,可是夾在中間的這個片美術用插件對它作了uv動畫,一旦啓動遊戲就會實例化成爲一個獨立的材質球。在進行DrawCall檢查的時候發現中間這層片一旦隱藏,就會致使下降2個DrawCall。最開始覺得是材質的問題,仔細看了Shader以後看不出什麼端倪。把uv動畫的物體換成內置Diffuse就行了,可是換成任何其它半透明的shader都會有問題。動畫
就這樣我跟這個問題鬼扯了一個多小時。直到某一次偶然手欠,挪了一下中間那個片片,DrawCall少了一個,我才一拍腦殼,恍然大悟。spa
欲知前因後果,且聽我娓娓道來。插件
要渲染半透明物體,爲了可以獲得正確的渲染結果,對物體進行排序而且保證自後向前渲染是必須的。因此對於個人三個片片,引擎確定是先渲染最後面的那個片,再渲染中間的,再渲染最前面的。排序
批次合併的本質實際上是把材質徹底相同的物體集中在一塊兒進行渲染,這樣在渲染這幾個物體過程當中就再也不須要更換材質,節省掉幾回更換材質的開銷。遊戲
對於我例子中的狀況,若是中間的片片不加uv動畫,那它們就是三個材質徹底相同的物體,能夠毫無疑問的被合併成爲一個批次。圖片
如今,中間的片片加了一個uv動畫,它有了屬於本身的材質,咱們的3個物體共有2個材質,彷佛剩下兩個片片沒受影響,依然能夠在同一批次渲染?但其實不能了,由於從渲染順序上講,當渲染ObjA後須要渲染ObjB,此時材質球已經被切換掉了,再渲染ObjC還要切換一次材質。it
若是我把中間的片片移動一下位置,或者是隱藏掉它,讓它再也不成爲夾在中間的物體,那麼剩下兩個物體又可以從新合併批次了。class
由於內置的Diffuse Shader是一個不透明Shader。遊戲引擎在處理不透明(或AlphaTest)物體時,老是會比半透明物體先渲染,而且由於不存在混合的問題,因此也不須要保證自後向前渲。因此它的位置雖然還夾在中間,可是渲染時機已經被移動到了第一個。原理
首先想到的方式是簡單的移動,讓它不夾在中間。但這個方法有一個缺陷,若是有不少組這樣的物件擺在同一個場景中,就確定有帶動畫的物體夾在它們中間,批次仍是會被打破。渲染
因此我轉而改變帶動畫物體材質的RenderQueue,原理和Diffuse Shader同樣,這樣全部其它物體依然可以合併批次。
不管是哪一種方法,我都沒法作到讓帶uv動畫的那個物體看起來被夾在中間了,只是對於我目前的需求來說,是能夠接受的一個效果。
靜態的修改材質球的RenderQueue可讓物體更早或者更晚渲染,而無視它的空間位置。假設我把ObjB的RenderQueue增長了10,那麼它就會看起來擺在全部其它RenderQueue未經修改的物體的最前面,不管你在正面看仍是背面看。若是你真的須要在兩面看起來都是正確的,能夠給ObjB添加一個組件,間隔固定的時間判斷玩家攝像機和它的相對位置。根據玩家攝像機在它的前面仍是後面,動態的決定把RenderQueue增長仍是減小,就能夠了。