天天看點

threejs加載obj模型_模型導入之優雅姿勢——glTF

threejs加載obj模型_模型導入之優雅姿勢——glTF

沒錯我現在算是入坑圖形學了,這是我在知乎的第一篇有關文章。我決定還是分享一些自己的圖形學随筆,也許沒那麼高端,但一定是原創。既是展示自己,也說不定能幫到别人。大佬若有看到瑕疵還望輕噴~

這篇文章适合正在學圖形學,尤其是在造渲染器輪子的同學看。

這篇文章并沒有講實質的圖形學技術,但應該還是很有價值的,如果你之前沒聽說過glTF的話。

自己動手造輪子寫渲染器的人都會知道,很麻煩的原因之一,就是需要自己寫模型導入的部分。

這部分并不能簡單地使用一行代碼調庫來解決,因為最終你總得将parse過的模型資料(無論是你自己parse的,還是調庫parse的)填入你自己定義的Primitive, Material, Mesh之類的對象裡面。

這時通常會有2種選擇:

  1. 使用萬能的assimp庫導入,它支援常見的3D模型/場景格式的解析。然後自己再從assimp定義的中間格式填入自己的類裡面。這樣可以省一部分力,因為我自己是懶得寫parser的,即使自己寫了,完整性也會差很多,到時導入可能會遇到各種不相容的解析失敗問題。

于是當時我就用assimp從obj檔案裡僅讀入網格資料,滿足了當時的需求。

後來我實作了PBR材質,模型自然也就需要三種貼圖(使用metallic workflow)。我也想從obj檔案讀出有關貼圖檔案的資訊,這時就發現obj格式裡的貼圖格式還是傳統的三種specular, diffuse, glossiness(用這三種貼圖也是可以實作PBR的,不過就不是metallic workflow了,而是specular workflow,計算出射光radiance的公式會稍有不同)

後來學習了更多的圖形知識,就知道了場景中的物體,還需要包含好多好多的屬性,比如emissive map,比如這個物體是不是雙面都看得到的(也就是禁不禁用face culling),比如這個物體是不是透明的(也就是使用blend還是depth test)。這些屬性,obj都沒有定義良好。當然了,obj附屬的mtl檔案,是可以添加自定義的屬性字段的,但仍覺得不妥:誰知道3D模組化者和你自己用的字段是不是一樣的呢?

2. 第二個解決方案就是,自己定義一種格式,存儲需要的屬性。各遊戲引擎肯定是這樣。但這不應該是一個小輪子所重點關注的地方,而且我更希望能使用公開統一的格式——别人模組化導出了,我的渲染器就能用。

是以這個方法也被我放棄了。一直以來,我的小輪子就隻能畫些uv球,平面,以及單個3D模型。而我一直有個願望,就是把那個著名的Sponza場景加載進來。

glTF

直到我在網上找到了glTF(gl Transmission Format)。

這是由Khronos組織定義的一種交換格式,也就是制定OpenGL标準的那個組織,足見其靠譜程度。

glTF也被稱作“3D界的jpeg”,足見其标準化程度。

接着讀了下它的介紹,馬上就愛了:

  • glTF 2.0原生支援metallic workflow的PBR材質
  • glTF格式其實是一個檔案夾,包含一個基于json的屬性檔案,一個二進制檔案用來放頂點資料,以及各種圖檔作為紋理。這樣解析起來就很簡單。事實上,使用rapidjson庫,我用1天就寫好了場景加載的代碼(又用了1天調試)。
  • 它兼顧了可讀性與加載速度。依我現在的使用經驗來看,這部分展現在頂點的存儲上。

頂點資料再也不像obj檔案那樣一行一個頂點,而是與OpenGL中vertex buffer相相容的方式用二進制存儲。甚至表示資料類型的int值,都與opengl裡的各枚舉類型數值(如GL_FLOAT)相同。這意味着隻要提前商量好格式,可以直接把頂點資料從檔案拷到記憶體,再從記憶體拷到顯存。

(這并沒有降低可讀性,因為即使是一行一個頂點,人也無法直接看出存的是啥。。)

  • 由于是面向渲染器的格式,諸如上文所提到的那些屬性,glTF都定義了。同時,通過讀glTF的specification,我也了解到3D模型該有的其他屬性。

格式雖好,但若大家都不用,那也是白搭。好在Blender, Windows 10自帶的3D Viewer等等檢視工具,都是支援glTF的。而且在glTF的GitHub頁面的Sample models裡,已經有足夠複雜的場景了,包括我想要的Sponza。

另外,在glTF的GitHub頁面順藤摸瓜,我發現了https://sketchfab.com/這個網站,許多模型品質都挺好,也都支援glTF格式下載下傳,目前看來模型資源是不成問題了。

最後還是放幾張自家小輪子渲染的圖吧:

threejs加載obj模型_模型導入之優雅姿勢——glTF

走樣很嚴重 軟陰影噪點也很多的Sponza

threejs加載obj模型_模型導入之優雅姿勢——glTF

Damaged Halmet 來自glTF GitHubhttps://www.zhihu.com/video/1215757547283628032

總結

如開頭所說,這篇文章并沒有讨論圖形學的技術,但glTF真的很值得了解:易學,易parse,支援廣泛,可以讓渲染器從此擺脫assimp...為何不用?我甚至覺得應該讓3D從業者一開始就接觸它而不是obj...