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...
Using ImmediateMesh
O ImmediateMesh é uma ferramenta prática para criar geometria dinâmica usando uma API no estilo do OpenGL 1.x. Isso o torna tanto acessível de usar quanto eficiente para malhas que precisam ser atualizadas a cada frame.
Gerar geometria complexa (com vários milhares de vértices) com essa ferramenta é ineficiente, mesmo que seja feito apenas uma vez. Em vez disso, ela foi projetada para gerar geometria simples que muda a cada frame.
Primeiro, você precisa criar um MeshInstance3D e adicionar um ImmediateMesh a ele no Inspetor.
Em seguida, adicione um script ao MeshInstance3D. O código para o ImmediateMesh deve ser colocado na função _process() se você quiser que ele seja atualizado a cada frame, ou na função _ready() se quiser criar a malha apenas uma vez e não atualizá-la. Se você gerar uma superfície apenas uma vez, o ImmediateMesh é tão eficiente quanto qualquer outro tipo de malha, pois a malha gerada é armazenada em cache e reutilizada.
Para começar a gerar geometria, você deve chamar surface_begin(). surface_begin() recebe um PrimitiveType como argumento. O PrimitiveType instrui a GPU sobre como organizar a primitiva com base nos vértices fornecidos, seja em triângulos, linhas, pontos etc. Uma lista completa pode ser encontrada na página de referência da classe Mesh.
Depois de chamar surface_begin(), você está pronto para começar a adicionar vértices. Os vértices são adicionados um por vez. Primeiro, você adiciona os atributos específicos do vértice, como normais ou UVs, usando surface_set_****() (por exemplo, surface_set_normal()). Em seguida, você chama surface_add_vertex() para adicionar um vértice com esses atributos. Por exemplo:
# 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))
Apenas os atributos adicionados antes da chamada de surface_add_vertex() serão incluídos naquele vértice. Se você adicionar um atributo duas vezes antes de chamar surface_add_vertex(), apenas a segunda chamada será usada.
Por fim, após adicionar todos os seus vértices, chame surface_end() para sinalizar que terminou de gerar a superfície. Você pode chamar surface_begin() e surface_end() várias vezes para gerar múltiplas superfícies para a malha.
The example code below draws a single triangle in the _ready() function.
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()
O ImmediateMesh também pode ser usado entre frames. Cada vez que você chama surface_begin() e surface_end(), uma nova superfície é adicionada ao ImmediateMesh. Se quiser recriar a malha do zero a cada frame, chame clear_surfaces() antes de chamar surface_begin().
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()
O código acima criará e desenhará dinamicamente uma única superfície em cada quadro.