Usar ImmediateMesh

El :ref:ImmediateMesh <class_ImmediateMesh> es una herramienta conveniente para crear geometría dinámica utilizando una API estilo OpenGL 1.x. Esto lo hace accesible de usar y eficiente para meshes que necesitan ser actualizadas en cada frame.

Generating complex geometry (several thousand vertices) with this tool is inefficient, even if it's done only once. Instead, it is designed to generate simple geometry that changes every frame.

Primero, necesitas crear una MeshInstance3D y añadirle una ImmediateMesh en el inspector.

A continuación, agregue un script al MeshInstance3D. El código para el ImmediateMesh debería ir en la función _process() si desea actualizar cada cuadro, o en la función _ready() si desea crear el Mesh una vez y no actualizarlo. Si quieres generar solo una vez una superficie, el ImmediateMesh is tan eficiente como cualquier otro tipo de mesh, ya que el Mesh generado se almacena en caché y se reutiliza.

To begin generating geometry you must call surface_begin(). surface_begin() takes a PrimitiveType as an argument. PrimitiveType instructs the GPU how to arrange the primitive based on the vertices given whether it is triangles, lines, points, etc. A complete list can be found under the Mesh class reference page.

Once you have called surface_begin() you are ready to start adding vertices. You add vertices one at a time. First you add vertex specific attributes such as normals or UVs using surface_set_****() (e.g. surface_set_normal()). Then you call surface_add_vertex() to add a vertex with those attributes. For example:

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

Only attributes added before the call to surface_add_vertex() will be included in that vertex. If you add an attribute twice before calling surface_add_vertex(), only the second call will be used.

Finally, once you have added all your vertices call surface_end() to signal that you have finished generating the surface. You can call surface_begin() and surface_end() multiple times to generate multiple surfaces for the mesh.

El código de ejemplo a continuación dibuja un solo triángulo en la función _ready().

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

El ImmediateMesh tambien puede ser utilizado a través de cada cuadro. Cada vez que llame surface_begin() y surface_end(), está añadiendo una nueva superficie al ImmediateMesh. Si deseas recrear el Mesh desde cero en cada cuadro, llame a clear_surfaces() antes de llamar 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()

El código de arriba creará dinámicamente y dibujará una sola superficie en cada cuadro.