OpenGL: Batch Rendering: Dovrebbe Trasformazioni avvengono sulla CPU o GPU?

0

Domanda

Sto sviluppando un motore di gioco 2D che 3D di supporto in futuro. Nella fase attuale di sviluppo, sto lavorando sul batch rendering. Come alcuni di voi sapranno, quando dosaggio grafica insieme, un supporto uniforme per colore (RGBA), le coordinate della texture, texture ID (texture indice) e il modello di matrice di trasformazione andare fuori dalla finestra, ma invece sono passati attraverso il vertex buffer. Ora, ho implementato passando il modello di posizioni, colore, texture coordinate, e la texture ID per il vertex buffer. Il mio vertex buffer formato simile a questo in questo momento:

float* v0 = {x, y, r, g, b, a, u, v, textureID};
float* v1 = {x, y, r, g, b, a, u, v, textureID};
float* v2 = {x, y, r, g, b, a, u, v, textureID};
float* v3 = {x, y, r, g, b, a, u, v, textureID};

Sto per integrare il calcolo in cui l'oggetto deve essere nel mondo spazio, utilizzando una matrice di trasformazione. Questo mi porta a chiedere:

Qualora la matrice di trasformazione moltiplicato per il modello di vertice posizioni sulla CPU o GPU?

Qualcosa da tenere a mente è che se mi passa il vertex buffer, devo caricare la matrice di trasformazione una volta per ogni vertice (4 volte al sprite), che mi sembra uno spreco di memoria. D'altra parte, moltiplicando il modello di vertice posizioni per la matrice di trasformazione, la CPU sembra che sarebbe più lento rispetto alla GPU concorrenza capacità.

Questo è come il mio vertex buffer formato sarebbe come se io ti calcolare la trasformazione della GPU:

float* v0 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v1 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v2 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v3 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};

La domanda è principalmente teoricamente guidato. Così, teorico e tecnico, la risposta sarebbe molto apprezzato. Ma per il riferimento, qui c'è il codice.

c++ glm-math glsl opengl
2021-11-24 03:43:20
2

Migliore risposta

1

Dovrebbe Trasformazioni avvengono sulla CPU o GPU?

Dipende molto dalla situazione a portata di mano. Se si reinvia i vertici di ogni fotogramma, è meglio benchmark ciò che è meglio per il vostro caso. Se si desidera animare senza dover ripresentare tutti i vostri vertici, non avete una scelta, ma per applicarlo sulla GPU.

Qualunque sia la ragione, se si decide di applicare le trasformazioni sulla GPU, ci sono modi migliori di fare che altro che duplicare la matrice per ogni vertice. Vorrei invece mettere le matrici di trasformazione in un SSBO:

layout(std430, binding=0) buffer Models {
    mat4 MV[]; // model-view matrices
};

e con un unico indice in ogni vertice del VAO:

struct Vert {
    float x, y, r, g, b, a, u, v;
    int textureID, model;
};

Il vertex shader può andare e recuperare la matrice completa in base all'indice di attributo:

layout(location = 0) in vec4 in_pos;
layout(location = 1) in int in_model;
void main() {
    gl_Position = MV[in_model] * in_pos;
}

Si può anche combinare con altre per-gli attributi di un oggetto, come il textureID.

EDIT: è possibile realizzare qualcosa di simile con le istanze e multi-draw. Anche se è probabile che sia più lento.

2021-11-24 17:20:51

Puoi dirci qualcosa di più su che cosa esattamente il modello sarebbe? Sto cercando di implementare e sono solo di ottenere uno sprite sullo schermo e penso che sia perché io non sono l'invio di informazioni corrette.
Christopher Barrios Agosto

@ChristopherBarriosAgosto un indice del modello a matrice in MV matrice: 0, 1, 2 ecc...
Yakov Galka

Dal rendering singolarmente trasformato quad, che sarà 0,0,0,0,1,1,1,1,2,2,2,2,... se si esegue il rendering con glDrawElements.
Yakov Galka

Ho capito! Funziona tutto ora! Scopre che era di passaggio e interpretare gli indici di destra, ma io stavo passando l'indice come un galleggiante di GLSL quando si era in attesa di un int. Ho fatto di ricevere un galleggiante e in GLSL il cast a int e non è interpretazione di tutti gli indici di destra. Lo devo fare in questo modo perché il vertex buffer è di tipo float. Grazie per tutto!
Christopher Barrios Agosto

@ChristopherBarriosAgosto: Complimenti che hai capito. 'vertex buffer è di tipo float' -- vertex buffer sono sequenze di byte. È possibile memorizzare structs in alcuni int campi e alcuni float campi.
Yakov Galka
0

Non sono sicuro di come il vostro codice motore realtà, sembra, ma suppongo che si presenta come qualsiasi altro programma OpenGL.

Se è così, nella mia esperienza, la matrice di trasformazione di solito dovrebbe essere passato per il vertex shader e essere applicato con il dato di vertice informazioni su GPU quando si disegna la scena. Per esempio:

//MVP matrix
GLuint MatrixID = glGetUniformLocation(shaderProgID, "MVP");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);

Ma se si desidera trovare le coordinate del mondo per tutti i vertici di un gruppo specifico, al di fuori della funzione di rendering, probabilmente hai bisogno di farlo con la CPU, o è necessario utilizzare alcune tecniche di programmazione parallela come OpenCL per fare il lavoro sulla GPU.

La cosa più importante è, perché specificamente vuoi le coordinate del mondo di informazioni al di fuori del disegno di procedura? Se si desidera semplicemente trovare il modello coordinate del mondo, si può semplicemente impostare un centro di coordinate per ogni modello in scena e solo traccia singola coordinata piuttosto che per l'intero gruppo di trame.

Il vertice di informazioni deve sempre essere in coordinate di modello e memorizzati nel vertex buffer, senza toccare, a meno che non si desidera applicare qualche modifica su di loro.

2021-11-24 03:57:24

Io sono di dosaggio grafica più insieme. Pertanto, non posso utilizzare uniformi per passare grafica' si trasforma, perché non sarò in grado di cambiare l'uniforme per la trasformazione tra una chiamata di disegno. Tuttavia, credo che l'utilizzo di SSBOs è una buona alternativa.
Christopher Barrios Agosto

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................