使用 SurfaceTool

SurfaceTool 提供了一个用于构造几何体的有用接口。该接口类似于 ImmediateMesh 节点。你设置每个顶点的属性(例如法线、uv、颜色),然后当你添加顶点时,它就会捕获这些属性。

SurfaceTool 还提供了一些有用的辅助函数,如 index()generate_normals()

属性是在添加每个顶点之前添加的:

GDScriptC#

  1. st.set_normal() # Overwritten by normal below.
  2. st.set_normal() # Added to next vertex.
  3. st.set_color() # Added to next vertex.
  4. st.add_vertex() # Captures normal and color above.
  5. st.set_normal() # Normal never added to a vertex.
  1. st.SetNormal(); // Overwritten by normal below.
  2. st.SetNormal(); // Added to next vertex.
  3. st.SetColor(); // Added to next vertex.
  4. st.AddVertex(); // Captures normal and color above.
  5. st.SetNormal(); // Normal never added to a vertex.

当使用 SurfaceTool 完成生成几何体后,调用 commit() 完成生成网格。如果将一个 ArrayMesh 传递给了 commit(),那么它就会在这个 ArrayMesh 的末尾附加一个新的表面。而如果没有传递任何信息,commit() 则返回一个 ArrayMesh。

GDScriptC#

  1. st.commit(mesh)
  2. # Or:
  3. var mesh = st.commit()
  1. st.Commit(mesh);
  2. // Or:
  3. var mesh = st.Commit();

代码创建一个有索引的三角形

GDScriptC#

  1. var st = SurfaceTool.new()
  2. st.begin(Mesh.PRIMITIVE_TRIANGLES)
  3. # Prepare attributes for add_vertex.
  4. st.set_normal(Vector3(0, 0, 1))
  5. st.set_uv(Vector2(0, 0))
  6. # Call last for each vertex, adds the above attributes.
  7. st.add_vertex(Vector3(-1, -1, 0))
  8. st.set_normal(Vector3(0, 0, 1))
  9. st.set_uv(Vector2(0, 1))
  10. st.add_vertex(Vector3(-1, 1, 0))
  11. st.set_normal(Vector3(0, 0, 1))
  12. st.set_uv(Vector2(1, 1))
  13. st.add_vertex(Vector3(1, 1, 0))
  14. # Commit to a mesh.
  15. var mesh = st.commit()
  1. var st = new SurfaceTool();
  2. st.Begin(Mesh.PrimitiveType.Triangles);
  3. // Prepare attributes for AddVertex.
  4. st.SetNormal(new Vector3(0, 0, 1));
  5. st.SetUV(new Vector2(0, 0));
  6. // Call last for each vertex, adds the above attributes.
  7. st.AddVertex(new Vector3(-1, -1, 0));
  8. st.SetNormal(new Vector3(0, 0, 1));
  9. st.SetUV(new Vector2(0, 1));
  10. st.AddVertex(new Vector3(-1, 1, 0));
  11. st.SetNormal(new Vector3(0, 0, 1));
  12. st.SetUV(new Vector2(1, 1));
  13. st.AddVertex(new Vector3(1, 1, 0));
  14. // Commit to a mesh.
  15. var mesh = st.Commit();

你可以选择添加一个索引数组, 可以通过调用 add_index() 将顶点添加到索引数组中, 也可以通过调用 index() 将顶点数组缩小以删除重复的顶点.

GDScriptC#

  1. # Creates a quad from four corner vertices.
  2. # add_index does not need to be called before add_vertex.
  3. st.add_index(0)
  4. st.add_index(1)
  5. st.add_index(2)
  6. st.add_index(1)
  7. st.add_index(3)
  8. st.add_index(2)
  9. # Alternatively:
  10. st.index()
  1. // Creates a quad from four corner vertices.
  2. // AddIndex does not need to be called before AddVertex.
  3. st.AddIndex(0);
  4. st.AddIndex(1);
  5. st.AddIndex(2);
  6. st.AddIndex(1);
  7. st.AddIndex(3);
  8. st.AddIndex(2);
  9. // Alternatively:
  10. st.Index();

同样, 如果你有一个索引数组, 但希望每个顶点都是唯一的(例如, 因为想在每个面而不是每个顶点使用唯一的法线或颜色), 可以调用 deindex() .

GDScriptC#

  1. st.deindex()
  1. st.Deindex();

如果你不想自行添加自定义法线,那么可以使用 generate_normals() 来添加,调用时机应该是在生成几何体之后、使用 commit()commit_to_arrays() 提交网格之前。调用 generate_normals(true) 会将最终的法线翻转。另外请注意,generate_normals() 只有在图元类型为 Mesh.PRIMITIVE_TRIANGLES 时有效。

你可能发现了,在生成的网格上,法线贴图或者其他一些材质属性看上去不对劲。这是因为对法线贴图而言,必需的是切线,这和法线是两码事。有两种解决方法,手动添加切线信息,或者使用 generate_tangents() 自动生成。这个方法要求每个顶点都已经具有 UV 和法线。

GDScriptC#

  1. st.generate_normals()
  2. st.generate_tangents()
  1. st.GenerateNormals();
  2. st.GenerateTangents();

默认情况下, 当生成法线时, 它们将以每个面为基础进行计算. 如果想要平滑的顶点法线, 在添加顶点时, 调用 add_smooth_group() . add_smooth_group() 需要在建立几何体时调用, 例如在调用 add_vertex() (如果没有索引)或 add_index() (如果有索引)之前.

Previous Next


© 版权所有 2014-present Juan Linietsky, Ariel Manzur and the Godot community (CC BY 3.0). Revision b1c660f7.

Built with Sphinx using a theme provided by Read the Docs.