Genera proceduralmente mesh con Godot 3.1 – approcci diversi

Come avevo bisogno per il mio Godot 3.x addon ho deciso di testare i diversi approcci che Godot offre per generare maglie 3D, finora (a mia conoscenza) ci sono 3 modi per farlo:

  • Utilizzare ImmediateGeometry
  • Utilizzare SurfaceTool
  • Generare direttamente un ArrayMeshDirectly generate an ArrayMesh

Quindi descriverò gli approcci di cui sopra e alla fine menzionerò i suoi pro e contro (nota, ho appena scoperto che la documentazione ufficiale di Godot per la versione 3.1 ha un articolo molto simile, quindi vale la pena dare un'occhiata qui, e in realtà alcuni degli esempi di codice sono dalla documentazione ufficiale).

Potrei dire, la prima volta è stato abbastanza frustrante come ho avuto pochissima conoscenza su 3D. Se si sta appena iniziando con 3D vi suggerisco di imparare alcune nozioni di base; Godot ha una documentazione sulla matematica 3D su vertici, trasofrms, ecc. Ma per capire come disegnare una mesh è sufficiente conoscere vertici, UV, normali e alcune altre cose. Quindi suggerisco di cercare la documentazione OpenGL, gli articoli di wikipedia, finché non hai un'idea più chiara, poi vai alla documentazione dell'API Godot e probabilmente la capirai molto più velocemente.

Geometria Immediata

Questa è stata la prima cosa che ho provato perché è stata la prima cosa che è venuto fuori googling.

Esempio di codice

Con questo si disegna la geometria in un modo simile a quello che si farebbe con i comandi OpenGL:

estende ImmediateGeometry

void _process(delta):
    - Pulire prima di disegnare.
    clear()

    - Iniziare a disegnare.
    begin(Mesh.PRIMITIVE_TRIANGLES)

    Preparare gli attributi per add_vertex.
    set_normal( Vector3(0, 0, 1))
    set_uv(Vector2(0, 0))
    Chiamare last per ogni vertice, aggiunge gli attributi di cui sopra.
    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))

    - Terminare il disegno.
    end()

Pro e contro

Beh, nella mia esperienza personale utilizzando la geometria immediata ci sono per lo più svantaggi, per esempio il rendering è più lento (soprattutto su mobile ho notato una grande differenza). Ma questo è da aspettarselo credo, come documentazione ufficiale menziona che questo dovrebbe essere utilizzato per geometrie semplici che cambiano frequentemente (immagino una volta per fotogramma).

Strumento Superficie

Poi ho testato SurfaceTool, principalmente perché ho trovato un addon che ha fatto uso di esso e ho cercato di imitare lo stesso approccio. Non siamo riusciti a trovarti abbastanza velocemente!

Esempio di codice

var st - SurfaceTool.new()

st.begin(Mesh.PRIMITIVE_TRIANGLES)
SUGGERIMENTO: L'aggiunta di un gruppo liscio genererà la superficie come liscia,
In caso contrario, verrà generato come piatto.
add_smooth_group(true)

Preparare gli attributi per add_vertex.
st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(0, 0))
Chiamare last per ogni vertice, aggiunge gli attributi di cui sopra.
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))

Creare indici, indici sono facoltativi.
st.index()

SUGGERIMENTO: se si desidera che le normali vengano calcolate automaticamente ricordandodi di chiamare questo metodo:
generate_normals()
SUGGERIMENTO: se si utilizza generate_normals non è necessario popolare le normali array con add_normal.

- Commit in una mesh.
mesh var : st.commit()

Il codice sopra è tratto dai documenti ufficiali, ho appena aggiunto un paio di CAP su come lisciare la superficie e come calcolare automaticamente le normali.

Pro e contro

Bene, molto probabilmente si finirà per utilizzare questo approccio in quanto ha molti vantaggi come:

  • Le normali possono essere calcolate automaticamente
  • è possibile scegliere di utilizzare l'ombreggiatura piatta o liscia
  • generazione è abbastanza veloce

Che cosa potrebbe non piacerti, o perché ho finito per utilizzare ArrayMesh:

  • Non è possibile smussare tra 2 mesh (ma è possibile tra le superfici della stessa mesh)

ArrayMesh

Quando ho capito che il mio addon non era abbastanza veloce ho deciso di indagare ulteriormente, ho finalmente ottenuto Godot codice sorgente complile sul mio pc, scaricato più addons che ha fatto cose simili, e così via. È stato allora che ho deciso di provare con ArrayMesh.

Esempio di codice

var vertici - PoolVector3Array()
vertices.push_back(Vector3(0, 1, 0))
vertices.push_back(Vector3(1, 0, 0))
vertices.push_back(Vector3(0, 0, 1))
: inizializzare ArrayMesh.
var arr_mesh - ArrayMesh.new()
matrici di var []
arrays.resize(ArrayMesh.ARRAY_MAX)
array[ArrayMesh.ARRAY_VERTEX] = vertici
Creare la mesh.
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, matrici)
var m - MeshInstance.new()
m.mesh - arr_mesh

Pro e contro

I vantaggi dell'utilizzo di ArrayMesh:

  • generazione più veloce della mesh (0,5 secondi sulla mia macchina in media)
  • se i vertici sono indicizzati, dimensioni inferiori su disco (metà del metodo della ventola della matrice SurfaceTool)
  • normals sono generati dal codice, quindi un migliore controllo su come li si desidera

Il problema con questo approccio è che:

  • Le normali devono essere calcolate manualmente (scrivere il proprio codice)

Conclusione

Ci è voluto un po 'per imparare a utilizzare i metodi di cui sopra, ma penso che valga la pena se si prevede di utilizzare la generazione procedurale nei vostri progetti Godot.

Personalmente ho finito per odiare ImmediateGeometry in quanto ha un sacco di problemi.

Ho intenzione di scrivere un paio di altri articoli su SurfaceTool (e anche MeshDataTool, lavorano un pò insieme in alcuni casi) e soprattutto ArrayMesh (che tra l'altro è una risorsa, a differenza degli altri 2 oggetti API). Voglio fornire esempi di codice poco più complessi che spero risulteranno utili.

Pubblicato in 3D, Videogiochi.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.