1. 程式人生 > >【轉】探索基礎元素---基於WebGL的H5 3D遊戲引擎BabylonJS

【轉】探索基礎元素---基於WebGL的H5 3D遊戲引擎BabylonJS

介紹

在本教程, 我們將學習如何使用Babylon.js建立基礎元素, 比如盒子, 球體, 和平面.

元素

我怎麼做到這個 ?

一個簡單的方法是通過訪問娛樂場演示場景 02來開始使用基礎元素. 你可能想使用彈出選單的’下載.zip壓縮包’ 選項. 你得到的zip壓縮包裡的index.html檔案,包含有你開始建立基礎元素所需的一切. 記住那個連結, 因為我們將更多的談論到它.

我確定你已經讀過Babylon.js初級教程 和 先前的教程, 因此你應該知道如何設定場景檔案格式. 因此, 我們不在談論它了. 我們將一步步通過娛樂場演示場景02來學習. 在新標籤頁或視窗中開啟那個連結, 然後返回此處, 我們馬上開始.

從盒子開始, 我們建立了高中基礎元素, 在該函式的最後將它們定位好(以防止它們堆疊起來). 讓們一一談論下各個基礎形狀/網格.

  • 建立一個盒子
var box = BABYLON.Mesh.CreateBox("box", 6.0, 場景, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名字,盒子大小, 它們將放到場景, 是否可更新?(如果該網格後面必須被更新) 和可選的面朝向(參見下面). 如果你需要預設表現那麼最後兩個引數可以忽略:

var box = BABYLON.Mesh.CreateBox("box", 6.0, scene);
  • 1
  • 建立一個球體
var sphere = BABYLON.Mesh.CreateSphere("sphere", 10.0, 10.0, 場景, false,  BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名字, 細分段數 (高度細節或不需), 大小, 將被放到的場景, 是否可更新?(如果該網格後面必須被更新) 和可選的面朝向(參見下面). 如果你需要預設的表現那麼最後兩個引數可以忽略:

var sphere = BABYLON.Mesh.CreateSphere("sphere", 10.0, 10.0, scene);
  • 1

記得根據你的網格物件到校調整細分段數 ;)

  • 建立一個平面
var plane = BABYLON.Mesh.CreatePlane("plane", 10.0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名字, 大小, 和將被放到的場景, 是否可更新?(如果該網格後面必須被更新) 和可選的面朝向(參見下面). 如果你需要預設的表現,那麼最後兩個引數可以忽略 :

var plane = BABYLON.Mesh.CreatePlane("plane", 10.0, scene);
  • 1
  • 建立一個碟片(或著一個規則多邊形)
var disc = BABYLON.Mesh.CreateDisc("disc", 5, 30, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名字, 半徑, 邊數, 場景, 可更新否和可選的朝向(參見下面). 如果你需要預設的表現,那麼最後兩個引數引數可以忽略:

var disc = BABYLON.Mesh.CreateDisc("disc", 5, 30, scene);
  • 1

根據tessellation 的值, 你可以建立一個多邊形: 
3產生一個三角形, 
4產生一個正方形, 
5產生一個五邊形, 
6產生一個六邊形, 7產生一個七邊形, 8產生一個八卦形, 以此類推.

  • 建立一個圓柱體
var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, 場景, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名稱, 高度, 頂直徑, 底直徑, 邊數, 高向細分度, 場景, 可更新否和可選的朝向(參見下面). 如果你需要預設表現,那麼最後兩個引數可以忽略:

var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, scene);
  • 1
  • 建立一個環面體
var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名稱, 直徑, 厚度, 邊數(高度細節或不是), 場景, 可更新否和可選的朝向(參見下面). 如果你使用預設表現那麼最後兩個引數可忽略 :

var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene);
  • 1
  • 建立一個結
var knot = BABYLON.Mesh.CreateTorusKnot("knot", 2, 0.5, 128, 64, 2, 3, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名稱, 半徑, tube, 半徑上分段數, tubularSegments, p, q, 場景, 可更新否和可選的朝向(參見下面). 如果你使用預設的表現那麼最後的兩個引數可以忽略 :

var knot = BABYLON.Mesh.CreateTorusKnot("knot", 2, 0.5, 128, 64, 2, 3, scene);
  • 1

將將在此處關於 結 學習更多知識.

  • 建立線型網格
var lines = BABYLON.Mesh.CreateLines("lines", [
    new BABYLON.Vector3(-10, 0, 0),
    new BABYLON.Vector3(10, 0, 0),
    new BABYLON.Vector3(0, 0, -10),
    new BABYLON.Vector3(0, 0, 10)
], scene);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

引數為: 名稱, [都好分隔的向量陣列], 場景.

我可以解釋線型網格是如何工作的, 當時我認為剋可以通過觀察上面的演示程式碼而知曉. 注意 [ 和 ]. 這兩個是陣列的起止標誌, 數值是Javascript的另一種值型別. 數組裡的頭個三元向量是線的開始地方. 那之後, 一個逗號, 然後下一個三元向量為畫線的線一個定位點. 然後, 又一個逗號, 和又一個三元向標示點新定位點. 可以新增任意多個向量, 但是注意最後一個三元向量之後沒有逗號跟隨. 請按照個格式組織向量陣列.

  • 繪製點劃線網格
var dashedlines = BABYLON.Mesh.CreateDashedLines("dashedLines", [v1, v2, ... vn], dashSize, gapSize, dashNb, 場景);
  • 1

引數為 : 名稱, [三元向量陣列], 劃線大小, 間隙大小, 段劃線數, 場景. 
作為許多線段, 每條段先都是以三元向量組的方式呈現在空間裡. 上面函式設定了這條點劃線裡線段的數量, 每段都是由兩個連續三元向量定義. 
劃線大小 和 間隙大小 是指點劃線裡每個劃線和之間間隙的相對大小.

你可能會被我們新的線系統吸引住.

  • 建立一條板帶

什麼是板帶 ?

首先, 想象一下一系列連續點定義的路徑. 
接下來,想象另一系列連續點,定義的一條路徑. 
現在, 如果你在第一條路徑和第二條路徑上互相間隔著連線點來構建三角形, 就像你係鞋帶的方式, 你就會得到一個板帶.

你的路徑間不需要平行. 它們甚至不需要是直線或在同一平面內. 
它們可以是任何你想要的方式. 板帶就沿著你定義的路徑.

現在, 想象一下, 不是兩條路徑, 你定義了許多連續的不同路徑. 
成對路徑間構成的所有板帶會結合起來形成連續表面.

var ribbon = BABYLON.Mesh.CreateRibbon("ribbon", [path1, path2, ..., pathn], false, false, 0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1

引數為: 名稱, 路徑陣列, 閉合陣列, 閉合路徑, 偏移量, 場景, 可更新否?(如果網格之後要被修改) 和可選的朝向 (參見下面).

  • 名稱: 一個字串, 你想要給你的造型物定義的名稱,
  • 路徑陣列: 填充路徑的陣列. 路徑也是陣列, 由一系列連續點 三元向量 填充. 你需要至少一條路徑形成板帶,而且每條路徑包含至少四個 三元向量,
  • 閉合陣列: 布林值, 如果為真, 則會由 路徑陣列 裡的第一條路徑和最後一條路徑產生一組額外的三角形,
  • 閉合路徑: 布林值, 如果為真, 則 路徑陣列 裡的每條路徑的最後一個點和其第一個點相連線,
  • 偏移量 : 正數 (預設值是 路徑 大小的一半), 僅當 路徑陣列 只有一條路徑時才必須指定. 此時板帶由該單條路徑上的 第 i 個點和第 i+偏移量 個點連線來構成. 這個引數會被忽略如果 路徑陣列 裡有多於一條路徑,
  • 場景 : 當前場景物件,
  • 可更新否: 布林值, 如果允許之後更新緞帶則設定為true,
  • 朝向: 期望的面朝向(BABYLON.Mesh.FRONTSIDE / BACKSIDE / DOUBLESIDE / DEFAULT).

如果僅需要使用預設表現則最後兩個引數可以被忽略:

var ribbon = BABYLON.Mesh.CreateRibbon("ribbon", [path1, path2, ..., pathn], false, false, 0, scene);
  • 1

如果你想知道處理該方法的更多細節, 你可能會閱讀引數化造型 部分.

  • * 創業一個管子*
var tube = BABYLON.Mesh.CreateTube("tube", [V1, V2, ..., Vn], radius, tesselation, radiusFunction, cap, scene, false, BABYLON.Mesh.DEFAULTSIDE);
  • 1
  • 2

引數為: 名稱, 路徑, 半徑, 曲面細分, 可選的半徑函式, 頭罩, 場景, 可更新否, 朝向.

  • 名稱: 字串, 管子網格的名字元, 
    • 路徑: 連續的三元向量陣列, 至少兩個三元向量,
    • 半徑: 數值, 管子的半徑, 當 半徑函式 引數設定為 null時使用,
    • 曲面細分: 徑向的段數,
    • 半徑函式: 可選的, 一個返回半徑值的 javascript 函式. 這個可以設定為 null,
    • 頭罩: BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL,
    • 可更新否: 布林值, 該管子後面是否可以被更新,
    • 朝向: 期望有用的朝向 (前向, 後像 或 雙向).

如果你僅僅要使用預設的表現則最後兩個引數可以忽略:

var tube = BABYLON.Mesh.CreateTube("tube", [V1, V2, ..., Vn], radius, tesselation, radiusFunction, cap, scene);
  • 1

管子也可以通過設定一個半徑函式而作為引數化造型 的方式使用.

可更新否

這個引數, 在每個網格建立方法裡出現… 告知該網格在建立後是否可以被更新. 
如果為 false (預設值), 則該網格數僅僅往GPU傳送一次. 
如果為 true, 則該網格資料可以被重新計算並在每幀重新整理時傳遞給GPU.

朝向

當一個網格被建立時, 可以為其提供一個可選的朝向. 
該朝向被用來提供可見性而且/或則光反射性. 
這個值有四個可能的值: 
* BABYLON.Mesh.FRONTSIDE,

  • BABYLON.Mesh.BACKSIDE,
  • BABYLON.Mesh.DOUBLESIDE,
  • BABYLON.Mesh.DEFAULT 這是預設值, 當前同 FRONTSIDE.

這個引數時可選的. 如果沒提供, 則 DEFAULT 值被設定.

(我們假設預設 backFaceCulling 被啟用了)

例如, 假設你建立一個基本形狀像, 比如一個盒子,球體或平面,你沒給它的設定材質. 
如果你到平面的背後或者盒子/球體的裡面, 你會注意到那些面時不可見的: Babylon.js 網格通常都是由預設的朝向 FRONTSIDE 構成. 這意味著每個面只有一邊可見. 
試驗下: http://www.babylonjs-playground.com/#14RNAU#4

如果你為網格應用了一個材質, 設定 material.backFaceCulling = false;, 同時用光源照明它, 你會注意到背面(或者裡面)… 現在可見了, 但是它卻不反射光. 同樣的原因: 預設的朝向仍然是 FRONTSIDE
(你可以用這個值來禁用 _backFaceCulling_ )

現在, 在你的網格建構函式裡僅僅改變 朝向 引數為 BABYLON.Mesh.BACKSIDE. (也移除你試驗的材質.) 你僅能看到平面的背面, 或者僅看到盒子和球體的裡面 (內部的面). 
試驗: http://www.babylonjs-playground.com/#14RNAU#5

如果你為網格提供一些材質, 你可以看到光源僅僅能照射到背面 (平面的)或者裡面 (盒子的, 球體的等). 
(你可以用_朝向_值來禁用 _backFaceCulling_ )

最後, 改變 朝向 引數值為 BABYLON.Mesh.DOUBLESIDE
正如你猜測的, 網格面現在兩邊可見了. 而且如果你提供了材質, 光也會在兩邊都反射. 
試驗: http://www.babylonjs-playground.com/#14RNAU#6

那麼為何不總是用 BABYLON.Mesh.DOUBLESIDE 作為預設值 ?

因為此值建立一個前向面的網格兩倍的頂點. 在其它方面, 你的網格消耗將翻倍. 
(你不能用 _BABYLON.Mesh.DOUBLESIDE_ 值來禁用 _backFaceCulling_)

更多基礎元素 - 地面

對這點, 我們在 娛樂場演示場景 02裡談論過該基礎元素, 但有更多的重要網格造型 (基礎元素)沒有包含在那個演示場景裡. 它們(下面例子)是Babylon.js建立’地面’的各種方法. 讓我們看看:

  • 建立一個地面
var ground = BABYLON.Mesh.CreateGround("ground", 6, 6, 2, scene);
  • 1

引數為: 名稱, 寬度, 縱深, 子分段數, 場景

我們的 娛樂場演示場景01使用了一個CreateGround建構函式… 所以你可以使用上面的連結來看看它的行為.

  • 使用高度圖建立地面
var ground = BABYLON.Mesh.CreateGroundFromHeightMap("ground", "heightmap.jpg", 200, 200, 250, 0, 10, scene, false, successCallback);
  • 1

引數為: 名稱, 高度圖路徑, 寬度, 縱深, 子分段數, 最小高度,最大高度, 場景, 可更新否, 成功回撥

高度圖地面很簡單, 但是我們決定建立一個獨立的教程講它, 以便能更多的講述Babylon.js的這個重要特徵. 請看我們的高度圖教程 以學習所有的高度圖地面知識.

  • 建立一個瓦片地圖

感謝論壇使用者Kostar111提供了這個方便的瓦片地圖構造方法. 這兒是建立一個瓦片地圖所需的基礎程式碼.


var precision = {
    "w" : 2,
    "h" : 2
};
var subdivisions = {
    'h' : 8,
    'w' : 8
};
var tiledGround = BABYLON.Mesh.CreateTiledGround("Tiled Ground", -3, -3, 3, 3, subdivisions, precision, scene, false);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

引數為: 名稱, 最小x值, 最小z值, 最大x值, 最大z, 細分數量 = 瓦片數量. (subdivisions.w : 寬度上的細分數量; subdivisions.h: 高度上的細分數量), 精度 = 一個瓦片內部的細分數量. (precision.w : 寬度上的精度; precision.h: 高度上的精度), 場景, 可更新否.

Kostar111 好人做到底了:為我們提供了一個關於如何使用瓦片地圖的很好教程. 點選這兒 檢視該教程. 在那個連結, Kostar111全面地說明了瓷磚地面的工作方式,還提供了一些Babylon.js遊樂場景, 很好地演示了一些它的許多用途.

結束語

就是這樣!現在你已經看了我們所有的基礎元素, 同時看了它們的一些使用方法. 保持關注教程裡這方面的內容, 因為新的基礎元素很快會被新增: 你會在這個章節裡發現更新了的名單和其所有引數的解釋. 
請自由設想你自己的基礎元素創意, 並把它們提交到論壇上. 如果你能,請幫助我們增加基礎元素列表.

下一步