mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-04 14:11:02 +03:00
Merge pull request #8272 from clayjohn/ImmediateMesh
Update references to the ImmediateMesh in the Procedural Geometry tutorial
This commit is contained in:
committed by
Max Hilbrunner
parent
ab70d6788f
commit
50d1bad093
@@ -3,25 +3,33 @@
|
||||
Using ImmediateMesh
|
||||
===================
|
||||
|
||||
Unlike the SurfaceTool or ArrayMesh, :ref:`ImmediateMesh <class_ImmediateMesh>` is an actual
|
||||
node. Being a node makes it quick to add to a scene and get visual output. It uses an OpenGL 1.x-style
|
||||
API like SurfaceTool, but it's actually designed to create meshes on the fly.
|
||||
The :ref:`ImmediateMesh <class_ImmediateMesh>` is a convenient tool to create
|
||||
dynamic geometry using an OpenGL 1.x-style API. Which makes it both approachable
|
||||
to use and efficient for meshes which need to be updated every frame.
|
||||
|
||||
Generating complex geometry (several thousand vertices) with this node is inefficient, even if it's
|
||||
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.
|
||||
|
||||
Before starting, you should clear the geometry by calling ``clear_surfaces()``. This ensures that
|
||||
you are not building upon the geometry from the previous frame. If you want to keep geometry between frames, do
|
||||
not call ``clear_surfaces()``.
|
||||
First, you need to create a :ref:`MeshInstance3D <class_meshinstance3d>` and add
|
||||
an :ref:`ImmediateMesh <class_ImmediateMesh>` to it in the Inspector.
|
||||
|
||||
To begin generating geometry you must call ``surface_begin()``. ``surface_begin()`` takes a ``PrimitiveType`` as an argument.
|
||||
``PrimitiveType`` is an OpenGL concept that 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
|
||||
Next, add a script to the MeshInstance3D. The code for the ImmediateMesh should
|
||||
go in the ``_process()`` function if you want it to update each frame, or in the
|
||||
``_ready()`` function if you want to create the mesh once and not update it. If
|
||||
you only generate a surface once, the ImmediateMesh is just as efficient as any
|
||||
other kind of mesh as the generated mesh is cached and reused.
|
||||
|
||||
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 :ref:`Mesh <class_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:
|
||||
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:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
@@ -31,37 +39,63 @@ Then you call ``surface_add_vertex()`` to add a vertex with those attributes. Fo
|
||||
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.
|
||||
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 mesh.
|
||||
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.
|
||||
|
||||
The example code below draws a single triangle.
|
||||
The example code below draws a single triangle in the ``_ready()`` function.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends ImmediateMesh
|
||||
|
||||
func _process(_delta):
|
||||
# Clean up before drawing.
|
||||
clear_surfaces()
|
||||
extends MeshInstance3D
|
||||
|
||||
func _ready():
|
||||
# Begin draw.
|
||||
surface_begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||
|
||||
# Prepare attributes for surface_add_vertex.
|
||||
surface_set_normal(Vector3(0, 0, 1))
|
||||
surface_set_uv(Vector2(0, 0))
|
||||
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.
|
||||
surface_add_vertex(Vector3(-1, -1, 0))
|
||||
mesh.surface_add_vertex(Vector3(-1, -1, 0))
|
||||
|
||||
surface_set_normal(Vector3(0, 0, 1))
|
||||
surface_set_uv(Vector2(0, 1))
|
||||
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))
|
||||
|
||||
surface_set_normal(Vector3(0, 0, 1))
|
||||
surface_set_uv(Vector2(1, 1))
|
||||
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.
|
||||
surface_end()
|
||||
mesh.surface_end()
|
||||
|
||||
The ImmediateMesh can also be used across frames. Each time you call
|
||||
``surface_begin()`` and ``surface_end()``, you are adding a new surface to the
|
||||
ImmediateMesh. If you want to recreate the mesh from scratch each frame, call
|
||||
``surface_clear()`` before calling ``surface_begin()``.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
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()
|
||||
|
||||
The above code will dynamically create and draw a single surface each frame.
|
||||
|
||||
@@ -30,9 +30,12 @@ by an array of positions called "vertices". In Godot, geometry is represented by
|
||||
What is a Mesh?
|
||||
---------------
|
||||
|
||||
Many things in Godot have mesh in their name: the :ref:`Mesh <class_Mesh>`, the :ref:`ArrayMesh <class_ArrayMesh>`,
|
||||
the :ref:`MeshInstance3D <class_MeshInstance3D>`, the :ref:`MultiMesh <class_MultiMesh>`, and
|
||||
the :ref:`MultiMeshInstance3D <class_MultiMeshInstance3D>`. While they are all related, they have slightly different uses.
|
||||
Many things in Godot have mesh in their name: the :ref:`Mesh <class_Mesh>`, the
|
||||
:ref:`ArrayMesh <class_ArrayMesh>`, the :ref:`ImmediateMesh
|
||||
<class_ImmediateMesh>`, the :ref:`MeshInstance3D <class_MeshInstance3D>`, the
|
||||
:ref:`MultiMesh <class_MultiMesh>`, and the :ref:`MultiMeshInstance3D
|
||||
<class_MultiMeshInstance3D>`. While they are all related, they have slightly
|
||||
different uses.
|
||||
|
||||
Meshes and ArrayMeshes are resources that are drawn using a MeshInstance3D node. Resources like
|
||||
Meshes and ArrayMeshes cannot be added to the scene directly. A MeshInstance3D represents one
|
||||
@@ -109,14 +112,16 @@ For more information about the SurfaceTool, please see the :ref:`SurfaceTool tut
|
||||
ImmediateMesh
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
ImmediateMesh is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The
|
||||
difference between ImmediateMesh and the SurfaceTool is that ImmediateMesh is a node itself that can be
|
||||
added to the scene tree and is drawn directly from the code, while The SurfaceTool generates a Mesh that needs to be added to
|
||||
a MeshInstance3D to be seen.
|
||||
ImmediateMesh is a mesh that uses an immediate mode style interface (like
|
||||
SurfaceTool) to draw objects. The difference between ImmediateMesh and the
|
||||
SurfaceTool is that ImmediateMesh is drawn directly with code dynamically, while
|
||||
the SurfaceTool is used to generated a Mesh that you can do whatever you want
|
||||
with.
|
||||
|
||||
ImmediateMesh is useful for prototyping because of its straightforward API, but it is slow because the geometry
|
||||
is rebuilt every frame. It is most useful for adding simple geometry for visual debugging (e.g. by drawing lines to
|
||||
visualize physics raycasts etc.).
|
||||
ImmediateMesh is useful for prototyping because of its straightforward API, but
|
||||
it is slow because the geometry is rebuilt each time you make a change. It is
|
||||
most useful for adding simple geometry for visual debugging (e.g. by drawing
|
||||
lines to visualize physics raycasts etc.).
|
||||
|
||||
For more information about ImmediateMesh, please see the :ref:`ImmediateMesh tutorial <doc_immediatemesh>`.
|
||||
|
||||
@@ -130,9 +135,9 @@ Both SurfaceTool and ArrayMesh are excellent for generating static geometry (mes
|
||||
Using an ArrayMesh is slightly faster than using a SurfaceTool, but the API is a little more challenging.
|
||||
Additionally, SurfaceTool has a few quality of life methods such as ``generate_normals()`` and ``index()``.
|
||||
|
||||
ImmediateMesh regenerates the mesh every frame, so it is much slower than ArrayMesh or SurfaceTool. However, if you
|
||||
need the geometry to change every frame anyway, it provides a much easier interface that may even be a little faster than generating
|
||||
an ArrayMesh every frame.
|
||||
ImmediateMesh is more limited than both ArrayMesh and SurfaceTool. However, if
|
||||
you need the geometry to change every frame anyway, it provides a much easier
|
||||
interface that can be slightly faster than generating an ArrayMesh every frame.
|
||||
|
||||
The MeshDataTool is not fast, but it gives you access to all kinds of properties of the mesh that you don't get with the others
|
||||
(edges, faces, etc.). It is incredibly useful when you need that sort of data to transform the mesh, but it is not a good idea
|
||||
|
||||
Reference in New Issue
Block a user