Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
使用 ImmediateMesh
ImmediateMesh 是一个使用 OpenGL 1.x 风格的 API 创建动态几何体的便捷工具。这使得它对于需要每帧更新的网格来说,既易于使用又高效。
使用这个工具生成复杂的几何体(几千个顶点)效率很低,即使只做一次。相反,它的设计是为了生成每一帧变化的简单几何体。
首先,你需要创建一个 MeshInstance3D 并在检查器中向其添加一个 ImmediateMesh。
接下来,将脚本添加到 MeshInstance3D 上。如果你希望 ImmediateMesh 每帧都更新,则应该把 ImmediateMesh 的代码放在 _process()
函数中;如果你想创建一次网格体而后不再更新它,则代码应放在 _ready()
函数中。如果仅生成一次表面,则 ImmediateMesh 与任何其他类型的网格一样高效,因为生成的网格会被缓存并重用。
必须调用 surface_begin()
才能开始生成几何体 。surface_begin()
将一个 PrimitiveType
作为参数。PrimitiveType
(图元类型)指示 GPU 如何根据给定的顶点来安排图元,可以是三角形、线、点等。完整的列表可以在 Mesh 的类参考页面中找到。
一旦你调用了 surface_begin()
,就可以开始添加顶点了。每次添加一个顶点,首先使用 surface_set_****()
(例如 surface_set_normal()
)添加顶点的特定属性,如法线或 UV。然后调用 surface_add_vertex()
来添加一个带有这些属性的顶点。例如:
# Add a vertex with normal and uv.
surface_set_normal(Vector3(0, 1, 0))
surface_set_uv(Vector2(1, 1))
surface_add_vertex(Vector3(0, 0, 1))
只有在调用 surface_add_vertex()
之前添加的属性才会被包含在该顶点中。如果在调用 surface_add_vertex()
之前添加属性两次,则仅第二次调用才会被使用。
最后,当添加了所有的顶点后,调用 surface_end()
来表示已经完成了网格的生成。你可以多次调用 surface_begin()
和 surface_end()
来为网格生成多个表面。
下面的示例代码在 _ready()
函数中绘制了一个三角形。
extends MeshInstance3D
func _ready():
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
mesh.surface_add_vertex(Vector3(-1, -1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 1))
mesh.surface_add_vertex(Vector3(-1, 1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(1, 1))
mesh.surface_add_vertex(Vector3(1, 1, 0))
# End drawing.
mesh.surface_end()
ImmediateMesh 也可以跨帧使用。每次调用 surface_begin()
和 surface_end()
时,你都会向 ImmediateMesh 添加一个新表面。如果你想在每一帧从头开始重新创建网格,请在调用 surface_begin()
之前先调用 clear_surfaces()
。
extends MeshInstance3D
func _process(delta):
# Clean up before drawing.
mesh.clear_surfaces()
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Draw mesh.
# End drawing.
mesh.surface_end()
上面的代码将在每个帧里动态地创建并绘制一个表面。