前提:美術很隨意得使用貼圖、材質,大量的材質雖然名稱不一樣,可是實際上材質屬性是相同的。node
因而,在導出時,在依次處理材質時,應該將新的材質屬性與已經收集到的材質進行對比,若是是相同的,則使用已存在的材質。工具
同時,雖然mesh中的submesh實際上是根據MatID來做劃分,可是通常狀況下,mesh中的submesh的vertex decl一般是徹底相同的。性能
那麼其實能夠將全部相同的vertex decl的submesh合併在同一個geometry(VB)中,submesh使用不一樣的index buffer來繪製,減小繪製時的VB切換。優化
因而,就有了shared geometry的共用,若是submesh的vertex decl與之不一樣(例如ABC是diffuseMap,DE是diffuseMap + specularMap,FGH是diffuseMap + specularMap + normalMap),則本身使用獨立的geometry來繪製。插件
另外,還要對於mesh中全部的submesh所使用的material進行排序,以減小沒必要要的state切換。orm
並且還有一個好處是,material的數量、mesh的大小都會減小,意味着減小了磁盤IO和文件解析所須要的時間。排序
接下來,就是本文的重點出現了。ip
問題總有2個:it
1. 想象中優化後的場景目錄的文件數量和大小,都應該會相應減小。但實際中發現,的確大多數模型數據都減小了十幾K到幾十K不等,可是少數模型的mesh尺寸變大了。效率
這個現象很奇怪,爲了分析緣由,我使用了工具對二者進行了二進制對比。
有意思的是,變大的文件,例如以前的十六進制數據爲: AB CD EF GH,變大的數據變成AB CD 00 00 EF GH 00 00。
經驗告訴我,確定是某些原先使用16bits描述的數值,如今變成32bits了。
相信朋友們已經猜到了緣由,即合併submesh以前,每個geometry大小都是65535之內,因而16bits IB就夠了
合併以後,vertex數量超過了65535,因而個人導出插件自動切換爲32bits IB來描述了
經過搜索資料,瞭解到10年前的GPU對於32bits IB的處理,除了帶寬上略有影響以外,並不會有額外的性能懲罰
而隨之優化帶來的batch減小以及VB等state切換所帶來的FPS提高,個人結論是這樣的優化是值得的
進一步的優化思考是,我目前是使用的triangle list保存的IB,即一個face使用3個index;若是改成triangle trip,那麼IB是頗有可能控制在65535以內的
2. 美術不必定會將同一個物體的多個子物體合併(Attach),例如手機:顯示屏幕、外殼、電池、天線,是分開爲多個mesh存在,而後合成一個group。
這樣子並不會影響實際使用中的操做,由於畢竟scene中仍是有一個叫「手機」的node。
可是理論上,咱們仍是但願這幾個物體合併在一塊兒,甚至想到說,既然上述的material和geometry的優化,那爲何不把整個場景都在導出時自動merge到一塊兒呢?
而後我想固然得寫了一個maxscript,在導出以前會自動將場景中全部的mesh合併在一塊兒。
可是實際狀況是,雖然感受上應該會更流暢,單個scene在觀察時也會有些許提高,可是當畫面是由多個scene分塊構成時,camera frustum的cull就廢掉了。
哪怕只有scene A的一棵小草被看到,整個scene都會被繪製出來,反而會影響到渲染效率。
優化無止境,同窗需努力。