OpenGL: Lot Renderer: ar Trebui să Transformări ce au loc pe CPU sau GPU?

0

Problema

Sunt în curs de dezvoltare un motor de joc 2D care va sprijini 3D în viitor. În aceasta faza actuală de dezvoltare, am de lucru pe lot renderer. După cum unii dintre voi poate știți, când dozare grafică împreună, uniforme suport pentru culoare (RGBA), coordonate de textură, textura ID (textura index), și modelul matricea de transformare ieși pe fereastră, dar în schimb sunt trecut prin vertex buffer. Acum, am implementat trecerea model pozițiile, culoare, textura coordonate, iar textura ID-ul de la vertex buffer. Mi vertex buffer format pare ca acest lucru chiar acum:

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};

Sunt pe cale de a se integra calcul în cazul în care obiectul ar trebui să fie în spațiu lume, folosind un matricea de transformare. Acest lucru mă conduce la întrebarea:

Ar trebui să matricea de transformare să fie înmulțită cu modelul pozițiile nodurilor de pe CPU sau GPU?

Ceva de a păstra în minte este că, dacă am trece la vertex buffer, va trebui să încărcați matricea de transformare o dată pe vertex (de 4 ori pe sprite) ceea ce mi se pare o pierdere de memorie. Pe de altă parte, înmulțirea model pozițiile nodurilor de matricea de transformare de pe CPU se pare ca ar fi mai lentă comparativ cu GPU-ul e concurenta capacități.

Acesta este modul meu vertex buffer format ar arăta dacă am calcula transforma pe 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};

Întrebarea este în mare parte teoretic condus. Deci, teoretic și tehnic răspunsul ar fi mult mai apreciat. Dar pentru referință, aici este codul.

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

Cel mai bun răspuns

1

Ar trebui să Transformări ce au loc pe CPU sau GPU?

Este într-adevăr depinde de situația de la mână. Dacă retrimiteți noduri fiecare cadru, cel mai bine este de a compara ceea ce este mai bine pentru cazul dumneavoastră. Dacă doriți să anima fără a retrimite toate nodurile, nu ai de ales, dar să-l aplice pe GPU.

Oricare ar fi motivul, dacă vă decideți să aplicați transformări pe GPU, există modalități mai bune de a face asta, altele decât duplicarea matrice pentru fiecare vertex. Am pus în loc de matrice de transformare într-o SSBO:

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

și a stoca un singur indice în fiecare nod în VAO:

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

Vertex shader poate du-te și adu o matrice plină bazează pe indicele de atribut:

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

Puteți chiar să-l combine cu alte per-obiect atribute, cum ar fi textureID.

EDIT: poti realiza ceva similar cu instanțiere și multi-draw. Deși este probabil să fie mai lent.

2021-11-24 17:20:51

Poti sa detaliezi mai mult asupra a ceea ce exact modelul ar fi? Am încercat să-l pună în aplicare și sunt doar un sprite de pe ecran și cred că este pentru că eu nu sunt trimiterea de informații corecte.
Christopher Barrios Agosto

@ChristopherBarriosAgosto un indice al matricei modelului în MV matrice: 0, 1, 2 etc...
Yakov Galka

Din moment ce sunt de randare individual transformat quad-uri, care vor fi 0,0,0,0,1,1,1,1,2,2,2,2,... dacă vă face cu glDrawElements.
Yakov Galka

Mi-am dat seama! Totul funcționează acum! Se pare că a fost în trecere și interpretarea indicilor de dreapta, dar am fost in trecere la index ca un flotor pentru GLSL când așteptam un int. Am făcut-o de a primi un flotor și în GLSL aruncat la un int și nu este interpretarea tuturor indicilor dreapta. Am să fac în acest fel pentru că vertex buffer-ul este de tip float. Vă mulțumesc pentru tot!
Christopher Barrios Agosto

@ChristopherBarriosAgosto: Felicitări că ți-ai dat seama. 'vertex buffer-ul este de tip float' -- vertex tampoanele sunt secvențe de octeți. Puteți stoca structs cu unele int domenii și unele float domenii.
Yakov Galka
0

Nu sunt sigur cum codul de motor, de fapt, se pare, dar presupun ca se pare ca orice alt program OpenGL.

Dacă este așa, din experiența mea, transforma matricea de obicei, ar trebui să fie trecut la vertex shader și să fie aplicate cu vertex informații pe GPU, atunci când trage de la locul faptei. De exemplu:

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

Dar dacă vrei să descoperi lumea coordonate pentru toate nodurile pentru un anumit grup, în afara de redare funcție, probabil, ai nevoie să-l facă pe CPU, sau va trebui să utilizați unele paralele tehnici de programare, cum ar fi OpenCL pentru a face munca pe GPU.

Cel mai important lucru este, de ce anume vrei lumea coordonatele informații în afara procedura de desen? Dacă doriți pur și simplu pentru a găsi modelul lumea de coordonate, puteți seta pur și simplu un centru de coordonate pentru fiecare model ai în scenă și singura piesă care singur a coordona mai degrabă decât întreaga plasă de grup.

Vârful de informații ar trebui să fie întotdeauna în modelul coordonează și stocate în vertex buffer cu nici o atingere, cu excepția cazului în care doriți să se aplice unele modificări pe ele.

2021-11-24 03:57:24

Eu sunt de dozare grafice multiple împreună. Prin urmare, eu nu pot folosi uniforme pentru a trece grafice se transformă, pentru că nu va fi capabil de a schimba uniforma pentru a transforma în între trage de apel. Cu toate acestea, cred că folosirea SSBOs este o alternativă foarte bună.
Christopher Barrios Agosto

În alte limbi

Această pagină este în alte limbi

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