Read this manual in English

Mesh 组件

Defold 本质是3D的. 即使 2D 材质也是以 3D 方法进行渲染, 再通过正交投射显示在屏幕上. Defold 也可以使用全3D素材, 也可以在运行时建立3D网格. 纯3D还是混合2D、3D游戏根据需要随意创作.

新建 Mesh 组件

Mesh 组件的创建和其他组件一样. 有两种方法:

  • Assets 浏览器里 的 Mesh 文件右键单击 , 然后选择 New... ▸ Mesh.
  • Outline 视图里的游戏对象上 right-clicking 然后选择 Add Component ▸ Mesh.

Mesh in game object

Mesh 组件包含一些列属性:

Mesh 属性

除了 Id, PositionRotation, 还有如下属性:

Material
3D网格材质.
Vertices
描述3D网格各种流顶点信息的缓冲文件.
Primitive Type
Lines, Triangles 还是 Triangle Strip.
Position Stream
位置 流. 流在顶点着色器输入数据时自动提供.
Normal Stream
法线 流. 流在顶点着色器输入数据时自动提供.
tex0
3D网格的纹理.

编辑时操作

3D网格组件建立好之后就可以使用编辑器和 Scene Editor 工具, 像普通游戏对象一样, 随意进行旋转缩放.

运行时操作

可以使用 Defold 缓存在运行时修改3D网格. 下面是一个使用三角面生成方块的例子:


-- 方块
local vertices = {
	0, 0, 0,
	0, 1, 0,
	1, 0, 0,
	1, 1, 0,
	1, 1, 1,
	0, 1, 0,
	0, 1, 1,
	0, 0, 1,
	1, 1, 1,
	1, 0, 1,
	1, 0, 0,
	0, 0, 1,
	0, 0, 0,
	0, 1, 0
}

-- 用位置流建立3D网格缓存
local buf = buffer.create(#vertices / 3, {
	{ name = hash("position"), type=buffer.VALUE_TYPE_FLOAT32, count = 3 }
})

-- 读取流数据, 写入三角形数据
local positions = buffer.get_stream(buf, "position")
for i, value in ipairs(vertices) do
	positions[i] = vertices[i]
end

-- 用三角形数据建立方块3D网格
local res = go.get("#mesh", "vertices")
resource.set_buffer(res, buf)

关于如何使用 Mesh 组件, 示例项目和代码片段, 详情参见 论坛发布帖子.

视锥体剔除

Mesh 不会被自动剔除, 因为它们具有动态特性, 而且无法确定位置数据的编码方式. 为了剔除网格, 需要使用 6 个浮点数, 把轴对齐的边界框设置为缓存元数据 (AABB 最小/最大):

buffer.set_metadata(buf, hash("AABB"), { 0, 0, 0, 1, 1, 1 }, buffer.VALUE_TYPE_FLOAT32)

材质常量

默认 mesh 材质常量可以使用 go.set()go.animate() 来修改 (参考 材质教程). 例如:

go.set("#mesh", "tint", vmath.vector4(1,0,0,1))
go.animate("#mesh", "tint", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,0,0,1), go.EASING_LINEAR, 2)
tint
3D网格颜色 (vector4). 四元数 x, y, z, 和 w 分别对应红, 绿, 蓝和不透明度.

顶点的局部/世界坐标空间

如果3D网格材质的坐标空间设为局部坐标空间, 则数据会原封不动传入着色器, 这样通常要在着色器程序里进行GPU顶点/法线的转换.

如果3D网格材质的坐标空间设为世界坐标空间, 则必须要么提供默认的 “位置” 和 “法线”, 流, 要么在编辑3D网格时, 在下拉菜单中选择好. 这样便于引擎把同样是世界坐标系的3D网格进行数据合批.