欧美日韩精品一区二区在线线,一级无码在线收看,精品国产高清91,久久精品欧美电影

# 幾何數(shù)據(jù)

渲染的基礎(chǔ)之一是幾何數(shù)據(jù)Geometry資源,它描述了一個(gè)模型的頂點(diǎn)信息、索引信息以及頂點(diǎn)的存取結(jié)構(gòu)。

一般來(lái)講,幾何數(shù)據(jù)是通過(guò)模型中自動(dòng)加載,或使用 內(nèi)置Geometry,但有時(shí)候我們需要去定制一些程序化生成的數(shù)據(jù)比如粒子等等,所以還是要明白如何去定制。

# 定制一個(gè)看看

const geometry = scene.createGeometry(
  vertexLayout, vertexBuffer,
  indexBuffer, indexType
)

可見(jiàn)構(gòu)造一個(gè)Geometry需要提供好幾個(gè)參數(shù),他們是:

# VertexLayout

首先是VertexLayout,用于描述頂點(diǎn)布局,舉個(gè)例子來(lái)說(shuō):

const layout = new xrFrameSystem.VertexLayout({
  attributes: [
    {
      name: 'a_position',
      format: xrFrameSystem.EVertexFormat.FLOAT2,
      offset: 0,
      usage: xrFrameSystem.EVertexLayoutUsage.POSITION,
    },
    {
      name: 'a_texCoord',
      offset: 8,
      format: xrFrameSystem.EVertexFormat.FLOAT2,
      usage: xrFrameSystem.EVertexLayoutUsage.UV0,
    },
    {
      name: 'a_color',
      format: xrFrameSystem.EVertexFormat.UBYTE4,
      offset: 16,
      usage: xrFrameSystem.EVertexLayoutUsage.COLOR,
    }
  ],
  stride: 20
});

這里定義了一個(gè)自定義的VertexLayout,其中有兩個(gè)參數(shù):

  1. attributes:描述了頂點(diǎn)的結(jié)構(gòu),即如何GPU將如何理解傳入的頂點(diǎn)數(shù)據(jù),比如第一個(gè)元素,其表示此頂點(diǎn)屬性在shader中名字為a_position,格式是FLOAT2,在頂點(diǎn)Buffer中偏移為0,并且用做POSITION。
  2. stride:描述了每個(gè)頂點(diǎn)所占帶寬的字節(jié)數(shù)。
  3. usage會(huì)影響到渲染這些數(shù)據(jù)時(shí)開啟的宏,詳見(jiàn)內(nèi)置效果。

# Buffer和Type

后面三個(gè)參數(shù)分別是頂點(diǎn)數(shù)據(jù)、索引數(shù)據(jù)索引格式,頂點(diǎn)數(shù)據(jù)按照布局結(jié)構(gòu)存儲(chǔ)著整個(gè)Geometry的頂點(diǎn)數(shù)據(jù),索引數(shù)據(jù)存儲(chǔ)著圖元對(duì)頂點(diǎn)的索引,而索引格式則是決定了索引數(shù)據(jù)的存儲(chǔ)格式,其可以為UINT16或者UINT32,如果為UINT16,則索引數(shù)據(jù)中的頂點(diǎn)索引值不得超過(guò)65535。

# 設(shè)置參數(shù)

在創(chuàng)建完一個(gè)新的幾何數(shù)據(jù)后,開發(fā)者還需要設(shè)置一些參數(shù)來(lái)讓它正確得運(yùn)作起來(lái),主要是SubMesh和包圍球/包圍盒。

# SubMesh

有了數(shù)據(jù)和布局后,幾何數(shù)據(jù)還需要提供一些信息去讓渲染器知道如何使用這些數(shù)據(jù),我們提供了叫做SubMesh的抽象,來(lái)將Geometry分割為數(shù)個(gè)部分:

// 添加一個(gè)SubMesh,其索引數(shù)據(jù)長(zhǎng)度為`length`個(gè)頂點(diǎn),第一個(gè)索引偏移為`offset`
geometry.addSubMesh(length, offset);

// 修改第`subMeshIndex`位置的SubMesh信息
geometry.modifySubMesh(subMeshIndex, length, offset);

這樣分割的原因主要是即便是同一個(gè)幾何數(shù)據(jù),也可能擁有不同的材質(zhì)來(lái)處理不同的部分,但是出于綜合考慮,目前渲染時(shí)幾何數(shù)據(jù)和材質(zhì)是一一對(duì)應(yīng)的,所以只支持一個(gè)SubMesh。

# 包圍球和包圍盒

對(duì)于每個(gè)幾何數(shù)據(jù)來(lái)說(shuō),在相機(jī)的剔除階段,都需要一個(gè)包圍球/包圍盒來(lái)決定其是否在可視范圍內(nèi),開發(fā)者可以通過(guò)以下方案來(lái)設(shè)置包圍球:

// `center`為球心相對(duì)于模型原點(diǎn)的偏移,`radius`是球的半徑
geometry.setBoundBall(center, radius);

或是設(shè)置包圍盒:

// `center`為球心相對(duì)于模型原點(diǎn)的偏移,`size`是盒的三維長(zhǎng)度,默認(rèn)會(huì)同步更新包圍球
geometry.setBoundBox(center, size);

# 更新數(shù)據(jù)

在某些場(chǎng)合,開發(fā)者還會(huì)需要去動(dòng)態(tài)更新頂點(diǎn)或索引數(shù)據(jù),比如粒子系統(tǒng),我們也提供了一些方案來(lái)完成這種需求(注意這種更新操作只能在Mesh已經(jīng)被提交到GPU后使用):

// 從字節(jié)偏移`offset`開始,將`buffer`整個(gè)更新到頂點(diǎn)數(shù)據(jù)。
geometry.uploadVertexBuffer(offset, buffer);

// 從字節(jié)偏移`offset`開始,將`buffer`整個(gè)更新到索引數(shù)據(jù)。
geometry.uploadIndexBuffer(offset, buffer);

之后便可以使用這個(gè)幾何數(shù)據(jù)了。

# 注冊(cè)到資源系統(tǒng)

和其他資源一樣,我們提供了一套注冊(cè)機(jī)制來(lái)讓開發(fā)者定制在xml中也可以被引用的幾何數(shù)據(jù):

xrFrameSystem.registerGeometry('custom', scene => {
  return scene.createGeometry(
    vertexLayout, vertexBuffer,
    indexBuffer, indexType
  );
});

注冊(cè)后在schema中類型指定為geometry的數(shù)據(jù),便可以使用custom這個(gè)資源id引用到創(chuàng)建的資源了。