Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Использование SurfaceTool

The SurfaceTool provides a useful interface for constructing geometry. The interface is similar to the ImmediateMesh node. You set each per-vertex attribute (e.g. normal, uv, color) and then when you add a vertex it captures the attributes.

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.

Когда вы закончите генерировать свою геометрию с помощью SurfaceTool, вызовите commit(), чтобы завершить генерацию сетки. Если ArrayMesh передается в commit(), то он добавляет новую поверхность в конец ArrayMesh. В то время как, если ничего не передано, commit() возвращает ArrayMesh.

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()

Вы можете дополнительно добавить массив индексов, либо вызвав 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()

Аналогично, если у вас есть массив индексов, но вы хотите, чтобы каждая вершина была уникальной (например, потому что вы хотите использовать уникальные нормали или цвета для каждой грани, а не для каждой вершины), вы можете вызвать deindex().

st.deindex()

Если вы не добавляете пользовательские нормали самостоятельно, вы можете добавить их с помощью generate_normals(0), который следует вызывать после генерации геометрии и перед фиксацией сетки с помощью commit() или commit_to_arrays(). Вызов generate_normals(true) перевернет результирующие нормали. В качестве дополнительного примечания, generate_normals() работает только в том случае, если для примитивного типа задано значение "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()

По умолчанию, при генерации нормалей, они будут вычисляться для каждого лица. Если вы хотите получить гладкие вершинные нормали, при добавлении вершин вызовите add_smooth_group(). add_smooth_group() нужно вызывать во время построения геометрии, например, перед вызовом add_vertex() (если он не индексирован) или add_index() (если индексирован).