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...
使用 SurfaceTool¶
SurfaceTool 提供了一个用于构造几何体的有用接口。该接口类似于 ImmediateMesh 类。你设置每个顶点的属性(例如法线、uv、颜色),然后当你添加顶点时,它就会捕获这些属性。
SurfaceTool 还提供了一些有用的辅助函数,如 index() 和 generate_normals()。
属性是在添加每个顶点之前添加的:
st.set_normal() # Overwritten by normal below.
st.set_normal() # Added to next vertex.
st.set_color() # Added to next vertex.
st.add_vertex() # Captures normal and color above.
st.set_normal() # Normal never added to a vertex.
st.SetNormal(); // Overwritten by normal below.
st.SetNormal(); // Added to next vertex.
st.SetColor(); // Added to next vertex.
st.AddVertex(); // Captures normal and color above.
st.SetNormal(); // Normal never added to a vertex.
当使用 SurfaceTool 完成生成几何体后,调用 commit() 完成生成网格。如果将一个 ArrayMesh 传递给了 commit(),那么它就会在这个 ArrayMesh 的末尾附加一个新的表面。而如果没有传递任何信息,commit() 则返回一个 ArrayMesh。
st.commit(mesh)
# Or:
var mesh = st.commit()
st.Commit(mesh);
// Or:
var mesh = st.Commit();
代码创建一个有索引的三角形
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
st.add_vertex(Vector3(-1, -1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 1))
st.add_vertex(Vector3(-1, 1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(1, 1))
st.add_vertex(Vector3(1, 1, 0))
# Commit to a mesh.
var mesh = st.commit()
var st = new SurfaceTool();
st.Begin(Mesh.PrimitiveType.Triangles);
// Prepare attributes for AddVertex.
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 0));
// Call last for each vertex, adds the above attributes.
st.AddVertex(new Vector3(-1, -1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 1));
st.AddVertex(new Vector3(-1, 1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(1, 1));
st.AddVertex(new Vector3(1, 1, 0));
// Commit to a mesh.
var mesh = st.Commit();
你可以选择添加一个索引数组, 可以通过调用 add_index() 将顶点添加到索引数组中, 也可以通过调用 index() 将顶点数组缩小以删除重复的顶点.
# Creates a quad from four corner vertices.
# add_index does not need to be called before add_vertex.
st.add_index(0)
st.add_index(1)
st.add_index(2)
st.add_index(1)
st.add_index(3)
st.add_index(2)
# Alternatively:
st.index()
// Creates a quad from four corner vertices.
// AddIndex does not need to be called before AddVertex.
st.AddIndex(0);
st.AddIndex(1);
st.AddIndex(2);
st.AddIndex(1);
st.AddIndex(3);
st.AddIndex(2);
// Alternatively:
st.Index();
同样, 如果你有一个索引数组, 但希望每个顶点都是唯一的(例如, 因为想在每个面而不是每个顶点使用唯一的法线或颜色), 可以调用 deindex() .
st.deindex()
st.Deindex();
如果你不想自行添加自定义法线,那么可以使用 generate_normals() 来添加,调用时机应该是在生成几何体之后、使用 commit() 或 commit_to_arrays() 提交网格之前。调用 generate_normals(true) 会将最终的法线翻转。另外请注意,generate_normals() 只有在图元类型为 Mesh.PRIMITIVE_TRIANGLES 时有效。
你可能发现了,在生成的网格上,法线贴图或者其他一些材质属性看上去不对劲。这是因为对法线贴图而言,必需的是切线,这和法线是两码事。有两种解决方法,手动添加切线信息,或者使用 generate_tangents() 自动生成。这个方法要求每个顶点都已经具有 UV 和法线。
st.generate_normals()
st.generate_tangents()
st.GenerateNormals();
st.GenerateTangents();
默认情况下, 当生成法线时, 它们将以每个面为基础进行计算. 如果想要平滑的顶点法线, 在添加顶点时, 调用 add_smooth_group() . add_smooth_group() 需要在建立几何体时调用, 例如在调用 add_vertex() (如果没有索引)或 add_index() (如果有索引)之前.