翻譯官方英文
https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/figures/gltfOverview-2.0.0b.png
glTF2.0總覽
glTF由Khronos組織設計和定義,實現在網絡上高效的傳輸3D內容。glTF的核心是通過一個Json的文件來描述3D場景的結構和組成。文件的頂層元素如下:
scenes,nodes:場景的基本結構
cameras:場景視口的配置
meshes:3D幾何對象
buffers,bufferViews,accessors:數據引用和數據佈局的描述
materials:定義對象如何被渲染(材質)
textures,images,samplers:對象表面觀感(紋理)
skins:頂點的蒙皮信息
animations:動畫
這些元素被包含在數組當中。對象之間的引用通過數組的索引進行關聯。
概念
glTF資產頂層元素之間的概念關係如下圖:
二進制數據引用
glTF資產的images和buffers可以引用包含呈現3d內容的外部文件。
"buffers": [
{
"url": "buffer01.bin",
"byteLength": 102040
}
],
"images": [
{
"url": "image01.png"
}
]
buffers指向包含幾何體或者動畫數據的二進制文件
images指向包含模型紋理信息的圖片文件
數據通過url來引用,但是也可以直接在json文件中包含數據urls。數據urls定義了MIME類型和一個base64編碼的數據字符串。
scenes和nodes
glTF的json文件可以包含scenes(和一個可選的默認scene)。每一個scene可以包含nodes索引數組。如下圖所示:
每個nodes可以包含子節點的索引數組。這就允許通過模型來表達一個場景的層次關係。
一個node可以包含本地變換。可以以一個matrix矩陣數組形式給出,也可以單獨的以translation(平移),rotation(旋轉)和scale(縮放)屬性給出。其中rotation是以一個四元數的形式給出。然後本地變換矩陣計算公式如下:
M = T * R * S
其中T,R 和S是通過translation,rotation和scale創建的矩陣數組。一個node的全部變換等於從root到相應的node的所有本地變換的乘積。
每個node也可能會引用到mesh或者camera,使用數組索引來指向meshes和cameras的數組。然後會將這些元素附加到node節點。如下圖:
在渲染期間,這些元素的實例會被創建和採用全部的變換矩陣變換。
一個node的translation(平移),rotation(旋轉)和scale(縮放)屬性也有可能會成爲一個動畫的目標:動畫會描述這些屬性如何隨着時間變化。因此被附加的對象將會允許對移動物體或者相機飛行進行建模。
nodes也可以使用在頂點蒙皮中:節點的層次結構可以用來定義動畫角色的骨架。然後node將會指向一個網格體或者蒙皮。蒙皮將會包含更多的信息關於如何將網格體基於當前的骨架姿勢進行改變。
meshes
meshes包含多個網格體。這些網格體指向需要渲染的幾何體數據,每一個mesh primitive有一個渲染mode,他是一個常量用來確定被渲染的是POINTS(點),LINES(線)或者TRIANGLES(面)。primitive會使用accessors的索引來指向indices和頂點的attributes。在渲染期間使用的material也被定義出來,使用了material數組的索引。具體格式參考下圖:
每個attributes通過索引來和accessor的數據映射。這些數據將會作爲渲染mesh的頂點屬性。看下面的頂點位置和法線的例子:
一個mesh可以定義多個變形targets。每個變形target描述原始mesh的變化。爲了定義一個mesh的變形,每個mesh可以包含一個targets數組。這些target通過索引去accessors裏面去獲取數據。一個mesh還可以包含一個weights(權重)數組,用來決定每個變形的target對渲染結果的影響。可以看下圖:
使用不同的權重來組合多個變形targets。例如模擬一個角色的不同面部表情。這些權重會在動畫中進行改變,進而實現內置幾何體的不同狀態。(備註:我認爲這些參數是用來處理動畫的)
buffers,bufferViews,accessors
buffers包含用於三維模型、動畫、蒙皮的數據。bufferViews增加了這些數據的結構信息。accessors定義了數據了類型和佈局。
buffers通過一個Url地址指向一個二進制文件。他是給定長度的原始數據庫的源。
bufferViews指向一個buffer。他定義了哪部分的buffer屬於bufferViews,通過byteOffset和byteLength來標識。另外還定義了可選的OpenGL buffer target。
accessors定義了bufferView的數據說明。他可以定義一個額外的byteOffset用來指向bufferView的開始,還定義了bufferView數據的類型和佈局。例如可以定義type爲VEC2和componentType爲5126。這表示數據爲一個loat精度的二維向量。所有數據的最大和最小值保存在min和max屬性中。
這3者之間的關係可以參考下圖:
多個accessors的數據可以同一個bufferView交錯。在這種情況,bufferVIew定義了一個byteStride屬性來定義每個元素之間字節大小。下圖通過一個示例詳細的描述了accessor到bufferView再到buffer之間的數據關係。
這種數據的設計爲了更好的配合OpenGL進行渲染。例如假設buffer中保存2d的紋理座標,bufferView的數據對於OpenGl的接口glBindBuffer。accessor對應OpenGl的接口glVertexAttribPointer。
Sparse accessors
當一個accessor中的元素只有很少一部分和默認的值不相同(這種場景經常在變形targets中),這些數據可以通過sparse數據表達。看下圖示例:
這裏accessor定義了scalar的float數據類型和整個元素的數量。sparse數據快包含了sparse數據元素的數量。values指向了sparse數據在哪個bufferView中。目標indices定義了指向哪個bufferView和componentType。
數據最終根據indices寫入accessor裏面。下圖示例描述了values 和indices 還有數據的關係。
materials
每個網格體都可能指向glTF資產中的某個material。materials描述了一個對象如何基於物理的材質屬性被渲染。這裏允許使用Physically Based Rendering(PBR)技術來確保被渲染對象的外觀具有一致性。
默認的material模型是Metallic-Roughness-Model。它通過0.0到1.0之間的值來描述一個materail的金屬相似度和表面粗糙度。這些屬性可以爲整個對象設置一個值,也可以從紋理中讀取。下圖爲0.0-1.0的粗糙度不同顯示外觀
下面通過一個示例來描述具體的參數如何填寫
Metallic-Roughness-Model模型的屬性設置都在定義在pbrMetallicRoughness的對象中。
baseColorTexture是被應用到對象中的主要紋理。
baseColorFactor包含了red,green,blue和alpha值的比例因子。如果沒有紋理使用的話,這些值將會應用到所有對象的顏色中去。
metallicRoughnessTexture通過blue顏色通道來表示金屬程度,通過green顏色通道來表示粗糙程度。metallicFactor和roughnessFactor會和上面的值相乘。如果沒有其他紋理,這些縮放因子反應所有對象的反射特性。
我們擴展了Metallic-Roughness-Model模型,增加了一些其他的屬性來反應對象的外觀。
normalTexture指向包含tangent-space法線信息的紋理,scale因子也會應用到這些法線中去。
occlusionTexture用來表示一個物體表面避光的區域,這樣渲染出來會更加黑暗。這個屬性在紋理的red通道里麪包含,通過strength來進行比例因子的縮放。
emissiveTexture用來表示物體表面被照亮的部分。他定義了從物體表面發出的光線的顏色。
emissiveFactor定義了這些顏色的縮放因子
下圖表達了meshes,materials和textures之間的關係。
cameras
每個node節點都可以引用定義在glTF資產中的camera。有兩種類型的camera:perspective(透視)和orthographic(正交),他們都定義了一個投影矩陣。
透視投影的裁剪平面的zfar參數是可選的,當這個參數被省略,會使用一個特殊的投影矩陣來實現無限的投影。
cameras的使用示例如下:
當一個node引用了camera之後,會創建一個camera的實例。camera實例的矩陣採用node節點的全局變換矩陣。
textures,images,samplers
textures包含了包含了渲染對象的紋理信息。Textures在materials中被引用,通過定義對象的基本顏色和物理參數來決定渲染對象的外觀。
texture由source和sampler組成。source指向某個image資產,sampler指向某個sampler。
images定義了被texture使用的圖片數據。圖片數據可以通過一個url來定位圖片的位置,也可以指向bufferview,通過MIME type來定義一個存儲在buffer view的圖片數據。
samplers描述了紋理的wrapping 和scaling。這些常量對應於OpenGL的glTexParamter參數。
skins
一個GlTF的資產可以包含必要實現頂點蒙皮的信息。依靠頂點蒙皮,他可以使網格體的頂點受到骨架當前姿勢的影響。這裏不翻譯了,暫時用不到。Computing the skinning matrix和animations由於暫時用不到,也跳過了。
Binary GlTF files
在標準的gltf格式中,有兩種選擇去包含外部的二進制數據比如緩存數據和紋理。他們可以指向外部的url或者使用數據url去嵌入到gltf的json數據中。當他們指向外部的url的時候,每個外部的資源意味着一次新的下載請求。當他們以base64的編碼形式的二進制嵌入到json內部時,會大幅度增加文件的大小。
爲了克服這些缺陷,有一個選項可以整合GlTF的json和二進制數據到一個二進制的gltf文件。這是一個以.glb爲後綴的小端序文件。他包含一個包含版本和數據結構的信息的header,和一個或者多個包含實際數據的chunks。第一個chunk總是包含json數據,剩下的數據包含二進制數據。具體的結構含義看下圖。
本文分享自微信公衆號 - WebHub(myWebHub)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。