OpenGL: Batch Renderer: By měla Transformace probíhat na CPU nebo GPU?

0

Otázka

Pracuji na 2D herní engine, který bude podporovat 3D v budoucnu. V této současné fázi vývoje, pracuji na batch renderer. Jak někteří z vás možná víte, když dávkové zpracování grafiky spolu, jednotná podpora pro color (RGBA), texturovací souřadnice, texturu ID (textury index), a model transformační matice jít ven z okna, ale místo toho jsou předávány prostřednictvím vertex buffer. Teď jsem implementoval absolvování model je pozice, barva, texturovací souřadnice, texturu ID do vertex bufferu. Můj vertex buffer, formát vypadá takto:

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

Chystám se integrovat výpočtu, kde je objekt by měl být ve světovém prostoru pomocí transformační matice. To mě vede k položit otázku:

Pokud by transformační matice vynásobí vrchol modelu pozice na CPU nebo GPU?

Něco mít na paměti, je, že když jsem se projít do vertex bufferu, musel bych nahrát transformační matice jednou na vrchol (4 krát za sprite), což se mi zdá jako ztráta paměti. Na druhou stranu, vynásobením model vertex pozic transformační matice na CPU se zdá, jako by to bylo pomalejší ve srovnání s GPU souběžnosti schopnosti.

To je, jak můj vertex buffer formátu by to vypadalo, kdybych výpočet transformace na 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};

Otázka je převážně teoreticky řízený. Takže, teoretickou a technickou odpověď by byla velmi ocenil. Ale pro porovnání, tady je kód.

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

Nejlepší odpověď

1

By měla Transformace probíhat na CPU nebo GPU?

To opravdu záleží na situaci po ruce. Pokud odešlete znovu vrcholy každý snímek, to je nejlepší měřítko, co je nejlepší pro váš případ. Pokud chcete animovat bez resubmitting všechny své vrcholy, nemáte na výběr, ale aplikovat to na GPU.

Ať už je důvod jakýkoliv, pokud se rozhodnete aplikovat transformace na GPU, tam jsou lepší způsoby, jak dělat to jiné než rozmnožovací matrice pro každý vrchol. Já bych místo toho dal transformační matice v SSBO:

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

a ukládat jeden index v každém vrcholu v VAO:

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

Vertex shader může jít a přinést plné matice na základě indexu atribut:

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

Můžete dokonce kombinovat je s jinými za-atributy objektů, jako textureID.

EDIT: můžete dosáhnout něco podobného s instancing a multi-draw. I když je pravděpodobné, že bude pomalejší.

2021-11-24 17:20:51

Můžete více rozvést, co přesně model? Snažím se realizovat a jsem pouze jeden sprite na obrazovce a myslím, že to je, protože já nejsem zaslání správné informace.
Christopher Barrios Agosto

@ChristopherBarriosAgosto index model matrix v MV pole: 0, 1, 2 atd...
Yakov Galka

Vzhledem k tomu, jste vykreslování jednotlivě transformován čtyřkolky, které budou 0,0,0,0,1,1,1,1,2,2,2,2,... pokud vykreslení glDrawElements.
Yakov Galka

Přišel jsem na to! Vše funguje teď! Ukázalo se, že jsem šel kolem a tlumočení indexy pravdu, ale já byl kolem indexu jako float GLSL, když to očekával, int. Udělal jsem to příjem plovák a v GLSL obsazení to do int a to je tlumočení všechny indexy pravdu. Musím to takhle udělat, protože vertex buffer je typu float. Děkuji vám za všechno!
Christopher Barrios Agosto

@ChristopherBarriosAgosto: Gratuluji, že jsi na to přišel. 'vertex buffer je typ float' -- vertex buffery jsou sekvence bajtů. Můžete uložit structs tam s nějakým int pole a některé float pole.
Yakov Galka
0

Nejsem si jistý, jak váš motor kód vlastně vypadá, ale předpokládám, že to vypadá jako jakékoli jiné OpenGL programu.

Pokud ano, podle mých zkušeností, transformace matice by měla být obvykle předána na vrcholu shader, a musí být aplikován s daným vrcholem, informace o GPU při kreslení scény. Například:

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

Ale pokud chcete najít svět souřadnice všech vrcholů na konkrétní skupiny, mimo vykreslovací funkce, budete pravděpodobně potřebovat, aby to na CPU, nebo budete muset použít nějakou paralelní programovací techniky jako je OpenCL dělat práci na GPU.

Nejdůležitější věc je, proč konkrétně chceš, aby se svět koordinuje informace mimo postup kreslení? Pokud chcete jednoduše najít model, světové souřadnice, můžete jednoduše nastavit střed souřadnic pro každý model máte ve scéně a sledovat pouze to, že jeden koordinaci spíše než celý mesh group.

Vertex informace by měly být vždy v modelových souřadnic a uloženy ve vertex bufferu s no touch, pokud chcete použít některé změny na nich.

2021-11-24 03:57:24

Jsem dávkování více grafických spolu. Proto nemohu použít uniformy projít grafiku se transformuje, protože to nebudu moci změnit uniformu pro transformaci mezi draw call. Nicméně, domnívám se, že využití SSBOs je velmi dobrou alternativou.
Christopher Barrios Agosto

V jiných jazycích

Tato stránka je v jiných jazycích

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