跳轉到內容

Celestia/3D 模型/CMOD 檔案

來自華夏公益教科書

Celestia 的內部模型物件由一組“材質”和一組“網格”組成。每個“網格”包含一組頂點定義,之後是一些“組”。每個“組”包含一個“組”型別規範,之後是屬於該組的先前定義的頂點列舉。這種結構完全對應於 CMOD 檔案中包含的專案。

CMOD 格式的 BN 描述

[編輯 | 編輯原始碼]

以下描述改編自 Celestia 原始碼中的註釋。

這是 ASCII cmod 檔案內容的近似巴克斯-諾爾正規化。為簡潔起見,類別 <unsigned_int> 和 <float> 這裡沒有定義——它們有明顯的定義。

 <modelfile>           ::= <header> <model>
              
 <header>              ::= #celmodel__ascii
              
 <model>               ::= { <material_definition> } { <mesh_definition> }
              
 <material_definition> ::= material
                           { <material_attribute> }
                           end_material
 
 <material_attribute>  ::= diffuse  <color>  |
                           specular <color>  | 
                           emissive <color>  | 
                           specpower <float> | 
                           opacity   <float> |
                           texture0 <string> |
                           blend add |             (v1.5.0 and later)
                           normalmap   <string> |  (v1.5.0 and later)
                           specularmap <string> |  (v1.5.0 and later)
                           emissivemap <string>    (v1.5.0 and later)

 <color>               ::= <float> <float> <float>
              
 <string>              ::= """ { letter } """
             
 <mesh_definition>     ::= mesh
                           <vertex_description>
                           <vertex_pool>
                          { <prim_group> }
                           end_mesh
 
 <vertex_description>  ::= vertexdesc
                           { <vertex_attribute> }
                           end_vertexdesc

 <vertex_attribute>    ::= <vertex_semantic> <vertex_format>
              
 <vertex_semantic>     ::= position | normal | color0 | color1 | tangent |
                           texcoord0 | texcoord1 | texcoord2 | texcoord3
 
 <vertex_format>       ::= f1 | f2 | f3 | f4 | ub4
              
 <vertex_pool>         ::= vertices <count>
                           { <float> }
 
 <count>               ::= <unsigned_int>
              
 <prim_group>          ::= <prim_group_type> <material_index> <count>
                           { <unsigned_int> }
 
 <prim_group_type>     ::= trilist | tristrip | trifan |
                           linelist | linestrip | points | 
                           sprites    (v1.5.0 and later)
              
 <material_index>      :: <unsigned_int> | -1

一些元素的說明

[編輯 | 編輯原始碼]

在 Celestia v1.5.0 或更高版本中,完整的材質定義將如下所示

material
diffuse 0.5 0.5 0.2
specular 1 1 1
specpower 30
opacity 1
texture0 "basetex.jpg"
normalmap "norm.png"
specularmap "specmask.jpg"
emissivemap "lights.jpg"
end_material

一些頂點屬性是

  • position - 位置 (必需)
  • texcoord0 - 主要紋理座標
  • texcoord1 ... texcoord3 - 附加紋理座標 (用於多重紋理)
  • color0 ... color1 - 主要和次要顏色
  • tangent - 表面切線 (用於凹凸貼圖)

頂點格式是

  • f1 - 一個浮點數
  • f2 - 兩個浮點數 (通常用於紋理座標)
  • f3 - 三個浮點數 (位置和法線)
  • f4 - 四個浮點數
  • ub4 - 四個無符號位元組 (顏色通常的格式)

基本型別是

  • trilist
  • tristrip
  • trifan
  • linelist
  • linestrip
  • points
  • sprites (v1.5.0 及更高版本)

三角帶和三角扇可能比三角形列表效率高得多。

示例 ASCII CMOD 檔案

[編輯 | 編輯原始碼]
#celmodel__ascii
# The above line is the 16-byte header; for binary files, it's
# #celmodel_binary

# material definitions follow--these must precede any meshes in the file
material       # index 0
emissive 0 1 0
opacity 0.5
end_material

# A material with a texture.  Texture filenames may use the wildcard
# character, which behaves exactly as it does within a .ssc file.
material	# index 1
emissive 1 1 1
texture0 "tropical-beach.*"
end_material

# There may be one or more meshes in a model file--this file happens
# to have just a single one
mesh

# The vertex description tells what attributes the vertices for this mesh
# have.  Each attribute in the description consists of a semantic and a
# data format.
vertexdesc
position f3
normal f3
texcoord0 f2
end_vertexdesc

# The vertex data--the number right after the keyword vertices is the
# number of vertices in the pool.
vertices 6
0 0 0 0 0 1 0 0
1 1 0 0 0 1 1 1
0 1 0 0 0 1 0 1
0 1 0 0 0 -1 0 1
1 1 0 0 0 -1 1 1
0 0 0 0 0 -1 0 0

# An arbitrary number of primitive groups follow

# The primitive group type is followed by a material index, then
# a count of the number of vertex indices in the group
trilist 0 3
0 1 2
trilist 1 3
3 4 5

# End of the mesh
end_mesh

# ---- end of cmod file ----

點精靈

[編輯 | 編輯原始碼]

從 Celestia v1.5.0 開始,CMOD 格式支援點精靈。它們可用於各種不同的體積渲染效果,用於模擬星雲、吸積盤、火山羽流或發動機排氣等現象。

與點精靈相關的 cmod 格式的更改很小。有一個新的材質屬性 (blend add),一個新的基本型別 (sprites) 和一個新的頂點屬性型別 (pointsize)。精靈紋理是材質定義中的 texture0。這是一個使用三個紅色精靈的非常基本的精靈 CMOD 示例

#celmodel__ascii
material
diffuse 1 0 0
texture0 "gaussian.jpg"
end_material

mesh
vertexdesc
position f3
pointsize f1
end_vertexdesc

vertices 3
1 0 0 0.25
2 0 0 0.25
3 0 0 0.25

sprites 0 3
0 1 2

end_mesh

CMOD 格式中有三個選項可用於影響幾何體——三角形、線、點或精靈——如何與背景混合。它們是 normal、blend 和 premultiplied,其中 'normal' 是預設值。

對於星雲網格,在材質定義中透過新增行 'blend add' 來指定加性混合可能很有用。這對於發射星雲尤其適用,但絕對不應用於馬頭星雲之類的暗星雲。加性混合物件具有無需相對於彼此進行深度排序的優點。這是一個使用加性混合和每個頂點顏色以使每個精靈具有不同顏色的稍微複雜一些的精靈 cmod

#celmodel__ascii
material
diffuse 1 0 0
texture0 "gaussian.jpg"
blend add
end_material

mesh
vertexdesc
position f3
pointsize f1
color0 f3
end_vertexdesc

# row of sprites: red, green, blue
vertices 3
1 0 0 0.25  1 0 0
2 0 0 0.25  0 1 0
3 0 0 0.25  0 0 1

sprites 0 3
0 1 2

end_mesh

對於點精靈,每個精靈都具有顏色和 alpha 值,它們與精靈紋理顏色和 alpha 值相乘,以產生片段顏色/alpha (Fr Fg Fb) 和 Fa。alpha 值可以看作是不透明度,但正如您將看到的,它並不總是以完全相同的方式對待。

Add 是最簡單的模式。如果背景顏色是 (Br Bg Bb),則最終顏色將是

Fa * (Fr Fg Fb) + (Br Bg Bb)

Normal 模式會導致背景被遮擋;alpha 值為 1 的片段將完全阻塞背景。

Fa * (Fr Fg Fb) + (1 - Fa) (Br Bg Bb)

最後,premultiplied 有點像 normal,只是它省略了與片段 alpha 的乘法。它假定由於透明度造成的任何顏色減少已經在建立幾何體時完成,因此稱為 premultiplied

(Fr Fg Fb) + (1 - Fa) (Br Bg Bb)

預乘混合的優點是它可以使用適當選擇的 alpha 和顏色值模擬新增或 normal 混合模式。例如,將 alpha 設定為零將給出與加性混合相同的結果。Cham:我認為這就是你所說的你想為粒子單獨啟用 add 的意思。

對於星雲,add 適用於發光、擴散的氣體,其中吸收不是一個主要的因素。理論上,預乘可以讓你混合發射和吸收粒子,但有一個問題:預乘和 normal 混合通常不可交換。為了獲得正確的結果,必須從後到前對粒子進行排序並按順序渲染它們,而 Celestia 目前不執行此操作,因為對大量粒子進行排序會導致效能大幅降低。事實上,混合的這種順序依賴性長期以來一直是即時 3D 圖形中的一個大難題,對於這個問題,仍然沒有完全令人滿意的解決方案。

使用三角帶 (由 Toti)

[編輯 | 編輯原始碼]

三角帶是 OpenGL 基本型別,它以這種方式繪製一組三角形

     1-----2 

     1-----2 
     \     / 
       \ / 
        3 

     1-----2 
     \     /\ 
       \ /    \ 
        3-----4 

     1-----2 
     \     /\ 
       \ /    \ 
        3-----4 
        \     / 
          \ / 
           5 


因此,我們可以將其儲存為:1,2,3,4,5 (5 個條目) 使用三角形列表,相同的三個三角形必須以這種方式儲存:1,2,3 2,3,4 3,4,5 (9 個條目,空格僅用於使文字清晰) 基本上,前兩個頂點定義了一個基準。對於每個新增的頂點 v,都會定義一個新的三角形。這個三角形由頂點 [v-2][v-1][v] 形成。

通常,對於由 T 個三角形組成的三角形列表,我們需要 3*T 個條目,但對於由 T 個三角形組成的三角帶,T+2 個條目就足夠了。因此,對於大型網格,您將節省 2/3 的資源。相同的方法可以應用於線段帶

     1---2 

     1---2 
         / 
       / 
       3 

     1---2 
         / 
       /  
       3----4 

     1---2 
         / 
       /  
       3----4 
           / 
         / 
         5 


如果上面的網格被定義為線段列表:1,2 2,3 3,4 4,5 (8 個條目)。如果它被定義為線段帶:1,2,3,4,5 (5 個條目) 線段列表需要 2*L 個條目來定義一組 L 條線段。線段帶僅需要 L+1 個條目來定義相同的集合。對於大型網格,節省的資源約為 50%。

使用這些基本型別的常用方法是像往常一樣建模物件,然後使用最佳化工具從原始三角形轉換為三角帶等。我不知道是否有任何免費程式/庫可以做到這一點。當然,克里斯可以。

使用三角扇 (由 Toti)

[編輯 | 編輯原始碼]
            1-------2 
             \     / 
              \   / 
                3 

            1-------2 
          /  \     / 
         /    \   / 
        4------ 3 

       5------ 1-------2 
        \    /  \     / 
         \  /    \   / 
           4------ 3 


使用三角扇,上面的網格可以描述為 1,2,3,4,5 每個三角形都有頂點 [v0][v-1][v],其中 v0 是集合的第一個頂點。

正如您所看到的,它類似於三角帶,但第一個頂點始終是三角扇的中心。您需要 T+2 個條目來定義 T 個三角形,因此它的效率與三角帶一樣高 (但通常它可以在三角帶無法使用的地方使用)

使用這些基本元素的優勢在於,您可以節省磁碟、匯流排和記憶體資源,因為網格描述的體積較小。

華夏公益教科書