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...
Utilisation de SurfaceTool
Le SurfaceTool fournit une interface utile pour construire de la géométrie. L'interface est similaire à la classe ImmediateMesh. Vous définissez chaque attribut par vertex (par ex. normale, uv, couleur) et ensuite, lorsque vous ajoutez un vertex, il capture les attributs.
SurfaceTool fournit également quelques fonctions d'aide utiles comme index() et generate_normals().
Les attributs sont ajoutés avant l'ajout de chaque sommet :
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
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.
When finished generating your geometry with the SurfaceTool,
call commit() to finish generating the mesh. If an ArrayMesh is passed
to commit(), then it appends a new surface to the end of the ArrayMesh. While if nothing is passed
in, commit() returns an ArrayMesh.
# Add surface to existing ArrayMesh.
st.commit(mesh)
# -- Or Alternatively --
# Create new ArrayMesh.
var mesh = st.commit()
st.Commit(mesh);
// Or:
var mesh = st.Commit();
Le code ci-dessous crée un triangle sans indices.
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();
You can optionally add an index array, either by calling add_index() and adding
vertices to the index array manually, or by calling index() once,
which generates the index array automatically and
shrinks the vertex array to remove duplicate vertices.
# Suppose we have a quad defined by 6 vertices as follows
st.add_vertex(Vector3(-1, 1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(-1, -1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(1, -1, 0))
st.add_vertex(Vector3(-1, -1, 0))
# We can make the quad more efficient by using an index array and only utilizing 4 vertices:
st.add_vertex(Vector3(-1, 1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(-1, -1, 0))
st.add_vertex(Vector3(1, -1, 0))
# Creates a quad from four corner vertices.
# add_index() can be called before or after add_vertex()
# since it's not an attribute of a vertex itself.
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 we can use ``st.index()`` which will create the quad for us and remove the duplicate vertices
st.index()
// Suppose we have a quad defined by 6 vertices as follows.
st.AddVertex(new Vector3(-1, 1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(1, -1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
// We can make the quad more efficient by using an index array and only utilizing 4 vertices:
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
// 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 we can use `st.Index()` which will create the quad for us and remove the duplicate vertices.
st.Index();
De même, si vous avez un tableau d'index, mais que vous voulez que chaque sommet soit unique (par exemple parce que vous voulez utiliser des normales ou des couleurs uniques par face au lieu de par vertex), vous pouvez appeler deindex().
st.deindex()
st.Deindex();
Si vous n'ajoutez pas les normales personnalisées vous-même, vous pouvez les ajouter en utilisant generate_normals(), qui doit être appelé après avoir généré la géométrie et avant de valider le maillage en utilisant commit() ou commit_to_arrays(). L'appel à generate_normals(true) inversera les normales résultantes. En remarque, generate_normals() ne fonctionne que si le type de primitive est défini sur Mesh.PRIMITIVE_TRIANGLES.
You may notice that normal mapping or other material properties look broken on
the generated mesh. This is because normal mapping requires the mesh to
feature tangents, which are separate from normals. You can either add custom
tangents manually, or generate them automatically with
generate_tangents(). This method requires that each vertex have UVs and
normals set already.
st.generate_normals()
st.generate_tangents()
st.commit(mesh)
st.GenerateNormals();
st.GenerateTangents();
By default, when generating normals, they will be calculated on a per-vertex basis (i.e. they will
be "smooth normals"). If you want flat vertex normals (i.e. a single normal vector per face), when
adding vertices, call add_smooth_group(i) where i is a unique number per vertex.
add_smooth_group() needs to be called while building the geometry, e.g. before the call to
add_vertex().