Generar procesalmente mallas con Godot 3.1 – diferentes enfoques

Como necesitaba para mi complemento Godot 3.x decidí probar los diferentes enfoques que Godot ofrece para generar mallas 3D, hasta ahora (hasta donde yo sé) hay 3 maneras de hacerlo:

  • Usar ImmediateGeometry
  • Usar SurfaceTool
  • Generar directamente un ArrayMesh

Así que voy a describir los enfoques anteriores y eventualmente mencionar sus pros y contras (nota, acabo de enterar Godot documentación oficial para la versión 3.1 tiene un artículo muy similar, por lo que vale la pena comprobar esto aquí, y en realidad algunos de los ejemplos de código son formar la documentación oficial).

Podría decir que la primera vez fue bastante frustrante, ya que tenía muy poco conocimiento sobre 3D. Si usted está empezando con 3D le sugiero aprender algunos conceptos básicos; Godot tiene documentación sobre matemáticas 3D sobre vértices, transofrms, etc. Pero para entender cómo dibujar una malla sólo necesita saber acerca de los vértices, UV, normales, y algunas cosas más. Así que sugiero buscar documentación de OpenGL, artículos de wikipedia, hasta que tenga una idea más clara, luego vaya a la documentación de godot API y probablemente lo entenderá mucho más rápido.

ImmediateGeometry

Esto fue lo primero que probé, ya que fue lo primero que salió googling.

Ejemplo de código

Con esto se dibuja la geometría de una manera similar a lo que haría con los comandos OpenGL:

extiende ImmediateGeometry

void _process(delta):
    • Limpie antes de dibujar.
    claro()

    • Comience a dibujar.
    begin(Mesh.PRIMITIVE_TRIANGLES)

    • Preparar atributos para add_vertex.
    set_normal( Vector3(0, 0, 1))
    set_uv(Vector2(0, 0))
    • Llamar al último para cada vértice, agrega los atributos anteriores.
    add_vertex(Vector3(-1, -1, 0))

    set_normal(Vector3(0, 0, 1))
    set_uv(Vector2(0, 1))
    add_vertex(Vector3(-1, 1, 0))

    set_normal(Vector3(0, 0, 1))
    set_uv(Vector2(1, 1))
    add_vertex(Vector3(1, 1, 0))

    • Fin del dibujo.
    final()

Pros y contras

Bueno, en mi experiencia personal usando geometría inmediata hay principalmente desventajas, por ejemplo, la representación es más lenta (especialmente en el móvil he notado una gran diferencia). Pero eso es de esperar supongo, como la documentación oficial menciona que esto debe ser utilizado para geometrías simples que cambian con frecuencia (me imagino como una vez por fotograma).

SurfaceTool

Luego probé SurfaceTool, principalmente porque encontré un complemento que hizo uso de él y traté de imitar el mismo enfoque. Y con esto finalmente pude hacer lo que quería, y creí que era lo suficientemente rápido para mis necesidades.

Ejemplo de código

var st á SurfaceTool.new()

st.begin(Mesh.PRIMITIVE_TRIANGLES)
CONSEJO: Añadir un grupo liso generará la superficie como lisa,
De lo contrario, se generará como plana.
add_smooth_group(true)

• Preparar atributos para add_vertex.
st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(0, 0))
• Llamar al último para cada vértice, agrega los atributos anteriores.
st.add_vertex(Vector3(-1, -1, 0))

st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(0, 1))
st.add_vertex(Vector3(-1, 1, 0))

st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(1, 1))
st.add_vertex(Vector3(1, 1, 0))

• Crear índices, los índices son opcionales.
st.index()

CONSEJO: Si desea que los normales se calculen automáticamente recuerde llamar a este método:
generate_normals()
CONSEJO: Si utiliza generate_normals no es necesario rellenar las normales arrray con add_normal.

• Comprométete con una malla.
var mesh á st.commit()

El código anterior se toma de los documentos oficiales, acabo de añadir un par de TIC sobre cómo suavizar la superficie y cómo calcular automáticamente las normales.

Pros y contras

Bueno, lo más probable es que termines usando este enfoque, ya que tiene muchas ventajas tales como:

  • Las normales se pueden calcular automáticamente
  • puede optar por usar sombreado plano o liso
  • generación es bastante rápido

Lo que puede no gustar, o por qué terminé usando ArrayMesh:

  • No se puede suavizar entre 2 mallas (pero se puede entre superficies de la misma malla)

ArrayMesh

Cuando me di cuenta de que mi complemento no era lo suficientemente rápido decidí investigar más, finalmente conseguí Godot código fuente cumplir en mi PC, descargado más complementos que hacían cosas similares, y así sucesivamente. Fue entonces cuando decidí probar con ArrayMesh.

Ejemplo de código

vértices de var : PoolVector3Array()
vertices.push_back(Vector3(0, 1, 0))
vertices.push_back(Vector3(1, 0, 0))
vertices.push_back(Vector3(0, 0, 1))
• Inicializar ArrayMesh.
var arr_mesh á ArrayMesh.new()
matrices var ? []
arrays.resize(ArrayMesh.ARRAY_MAX)
matric[ArrayMesh.ARRAY_VERTEX]es: vértices
• Cree la malla.
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, matrices)
var m á MeshInstance.new()
m.mesh á arr_mesh

Pros y contras

Las ventajas de utilizar ArrayMesh:

  • la generación más rápida de la malla (0,5 segundos en mi máquina en promedio)
  • si se indexan los vértices, tamaño más pequeño en el disco (la mitad del método de ventilador de matriz SurfaceTool)
  • normales se generan por código, así que mejor control sobre cómo desea que

El problema con este enfoque es que:

  • Las normales deben calcularse manualmente (escriba su propio código)

Conclusión

Tomó un tiempo aprender a usar los métodos anteriores, pero creo que vale la pena si planea usar la generación de procedimientos en sus proyectos de Godot.

Personalmente terminé odiando ImmediateGeometry ya que tiene un montón de problemas.

Estoy planeando escribir un par de artículos más sobre SurfaceTool (y también MeshDataTool, funcionan juntos en algunos casos) y especialmente ArrayMesh (que por cierto es un recurso, a diferencia de los otros 2 objetos de API). Quiero proporcionar ejemplos de código poco más complejos que espero que resulten útiles.

Posted in 3D, Videojuegos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.