procedural_geometry.rst 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. .. _doc_procedural_geometry:
  2. Procedural geometry generation
  3. ==============================
  4. Users often ask how to generate geometry from code. This is not very complicated, but it's not obvious.
  5. Godot provides a few classes entirely dedicated to make it this easy. Still, the best tool for the job depends
  6. entirely on the use case.
  7. SurfaceTool
  8. -----------
  9. This is the most common helper. :ref:`SurfaceTool<class_SurfaceTool>` is a class you can instantiate to generate :ref:`Meshes<class_Mesh>`, specifically *Mesh Surfaces*.
  10. It has a similar API to OpenGL 1.x, and it's meant for static content. This means, the mesh is generated once and then used.
  11. Here is a simple example of how to use it to add a single triangle.
  12. .. tabs::
  13. .. code-tab:: gdscript GDScript
  14. var st = SurfaceTool.new()
  15. st.begin(Mesh.PRIMITIVE_TRIANGLES)
  16. # Prepare attributes for add_vertex.
  17. st.add_normal(Vector3(0, 0, 1))
  18. st.add_uv(Vector2(0, 0))
  19. # Call last for each vertex, adds the above attributes.
  20. st.add_vertex(Vector3(-1, -1, 0))
  21. st.add_normal(Vector3(0, 0, 1))
  22. st.add_uv(Vector2(0, 1))
  23. st.add_vertex(Vector3(-1, 1, 0))
  24. st.add_normal(Vector3(0, 0, 1))
  25. st.add_uv(Vector2(1, 1))
  26. st.add_vertex(Vector3(1, 1, 0))
  27. # Create indices, indices are optional.
  28. st.index()
  29. # Commit to a mesh.
  30. var mesh = st.commit()
  31. Just explore the APIs and the possibilities.
  32. ImmediateGeometry
  33. -----------------
  34. Unlike *SurfaceTool*, :ref:`ImmediateGeometry<class_ImmediateGeometry>` is an actual node. It's similar in the "OpenGL 1.x" style API,
  35. but it's actually designed to create content on the fly and modify it every frame efficiently.
  36. Generating complex geometry (several thousand vertices) with this node is inefficient, even if it's done only once. Instead, *ImmediateGeometry* is designed to generate simple geometry that changes every frame.
  37. It's used similar to *SurfaceTool*.
  38. .. tabs::
  39. .. code-tab:: gdscript GDScript
  40. extends ImmediateGeometry
  41. void _process(delta):
  42. # Clean up before drawing.
  43. clear()
  44. # Begin draw.
  45. begin(Mesh.PRIMITIVE_TRIANGLES)
  46. # Prepare attributes for add_vertex.
  47. set_normal( Vector3(0, 0, 1))
  48. set_uv(Vector2(0, 0))
  49. # Call last for each vertex, adds the above attributes.
  50. add_vertex(Vector3(-1, -1, 0))
  51. set_normal(Vector3(0, 0, 1))
  52. set_uv(Vector2(0, 1))
  53. add_vertex(Vector3(-1, 1, 0))
  54. set_normal(Vector3(0, 0, 1))
  55. set_uv(Vector2(1, 1))
  56. add_vertex(Vector3(1, 1, 0))
  57. # End drawing.
  58. end()
  59. Arrays
  60. ------
  61. Lastly, the final way to do this is to create arrays themselves. This is the most efficient way to create static geometry, and is only
  62. recommended when SurfaceTool is not fast enough.
  63. Similar code as before, but draw a square using indices:
  64. .. tabs::
  65. .. code-tab:: gdscript GDScript
  66. var arrays = []
  67. arrays.resize(Mesh.ARRAY_MAX)
  68. var normal_array = []
  69. var uv_array = []
  70. var vertex_array = []
  71. var index_array = []
  72. normal_array.resize(4)
  73. uv_array.resize(4)
  74. vertex_array.resize(4)
  75. index_array.resize(6)
  76. normal_array[0] = Vector3(0, 0, 1)
  77. uv_array[0] = Vector2(0, 0)
  78. vertex_array[0] = Vector3(-1, -1, 0)
  79. normal_array[1] = Vector3(0, 0, 1)
  80. uv_array[1] = Vector2(0,1)
  81. vertex_array[1] = Vector3(-1, 1, 0)
  82. normal_array[2] = Vector3(0, 0, 1)
  83. uv_array[2] = Vector2(1, 1)
  84. vertex_array[2] = Vector3(1, 1, 0)
  85. normal_array[3] = Vector3(0, 0, 1)
  86. uv_array[3] = Vector2(1, 0)
  87. vertex_array[3] = Vector3(1, -1, 0)
  88. # Indices are optional in Godot, but if they exist they are used.
  89. index_array[0] = 0
  90. index_array[1] = 1
  91. index_array[2] = 2
  92. index_array[3] = 2
  93. index_array[4] = 3
  94. index_array[5] = 0
  95. arrays[Mesh.ARRAY_VERTEX] = vertex_array
  96. arrays[Mesh.ARRAY_NORMAL] = normal_array
  97. arrays[Mesh.ARRAY_TEX_UV] = uv_array
  98. arrays[Mesh.ARRAY_INDEX] = index_array
  99. var mesh = ArrayMesh.new()
  100. mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES,arrays)