OpenGL: Toplu İş Oluşturucu: Dönüşümler CPU veya gpu'da gerçekleşmeli mi?

0

Soru

Gelecekte 3D'yi destekleyecek bir 2D oyun motoru geliştiriyorum. Şu anki geliştirme aşamasında, toplu iş oluşturucu üzerinde çalışıyorum. Bazılarınızın bildiği gibi, grafikleri bir araya getirirken, renk (RGBA), doku koordinatları, doku kimliği (doku dizini) ve model dönüştürme matrisi için tekdüze destek pencereden dışarı çıkar, bunun yerine köşe arabelleğinden geçirilir. Şu anda, modelin konumlarını, rengini, doku koordinatlarını ve doku kimliğini köşe arabelleğine geçirmeyi uyguladım. Köşe tampon formatım şu anda böyle görünüyor:

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

Bir dönüşüm matrisi kullanarak nesnenin dünya uzayında nerede olması gerektiğini hesaplamayı entegre etmek üzereyim. Bu bana şu soruyu sormamı sağlıyor:

Dönüşüm matrisi, CPU veya gpu'daki model köşe konumları ile çarpılmalı mı?

Akılda tutulması gereken bir şey, eğer köşe arabelleğine geçirirsem, dönüşüm matrisini köşe başına bir kez (sprite başına 4 kez) yüklemem gerektiğidir ki bu benim için bir bellek kaybı gibi görünüyor. Öte yandan, model köşe konumlarını CPU üzerindeki dönüşüm matrisi ile çarpmak, GPU'nun eşzamanlılık yeteneklerine kıyasla daha yavaş olacak gibi görünüyor.

GPU'DAKİ dönüşümü hesaplarsam köşe arabellek biçimim böyle görünürdü:

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

Soru çoğunlukla teorik olarak yönlendirilir. Yani, teorik ve teknik bir cevap çok takdir edilecektir. Ama referans için, işte kod.

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

En iyi cevabı

1

Dönüşümler CPU veya gpu'da gerçekleşmeli mi?

Gerçekten eldeki duruma bağlı. Köşelerinizi her karede yeniden gönderirseniz, durumunuz için en iyi olanı kıyaslamak en iyisidir. Tüm köşelerinizi yeniden göndermeden animasyon yapmak istiyorsanız, bunu GPU'ya uygulamaktan başka seçeneğiniz yoktur.

Sebep ne olursa olsun, dönüşümleri GPU'ya uygulamaya karar verirseniz, her köşe için matrisi çoğaltmaktan başka bunu yapmanın daha iyi yolları vardır. Bunun yerine dönüşüm matrislerini bir ssbo'ya koyardım:

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

ve vao'daki her köşede tek bir dizin saklayın:

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

Köşe gölgelendiricisi, dizin özniteliğine göre tam matrisi alabilir ve alabilir:

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

Nesne başına diğer özniteliklerle bile birleştirebilirsiniz, örneğin textureID.

DÜZENLEME: örnekleme ve çoklu çizim ile benzer bir şey elde edebilirsiniz. Daha yavaş olması muhtemel olsa da.

2021-11-24 17:20:51

Olabilir ayrıntılı daha tam olarak hangi model olurdu? Bunu uygulamaya çalışıyorum ve ekranda yalnızca bir sprite alıyorum ve bunun doğru bilgiyi göndermediğim için olduğunu düşünüyorum.
Christopher Barrios Agosto

@ChristopherBarriosAgosto MV dizisindeki model matrisinin bir dizini: 0, 1, 2 vb...
Yakov Galka

Ondan beri sen are işleme bireysel olarak değiştirdi dörtlü, o olacak 0,0,0,0,1,1,1,1,2,2,2,2,... eğer render ile glDrawElements.
Yakov Galka

Ben de düşündüm bunu dışarı! Şimdi her şey çalışıyor! Endeksleri doğru bir şekilde aktarıp yorumladığım ortaya çıktı, ancak bir int beklediğinde endeksi glsl'ye kayan nokta olarak geçiriyordum. Bir şamandıra almasını sağladım ve glsl'de bir int'ye çevirdim ve tüm indeksleri doğru yorumlamıyor. Bunu bu şekilde yapmak zorundayım çünkü köşe tamponu float tipindedir. Her şey için teşekkür ederim!
Christopher Barrios Agosto

@ ChristopherBarriosAgosto: Bunu çözdüğünüz için tebrikler. 'köşe arabelleği kayan yazı tipindedir' -- köşe arabellekleri bayt dizileridir. Saklayabilirsiniz structs orada bazılarıyla int alanlar ve bazıları float alanlar.
Yakov Galka
0

Motor kodunuzun gerçekte nasıl göründüğünden emin değilim, ancak başka bir OpenGL programına benzediğini varsayıyorum.

Eğer öyleyse, tecrübelerime göre, dönüşüm matrisi genellikle köşe gölgelendiricisine aktarılmalı ve sahneyi çizdiğinizde gpu'da verilen köşe bilgileriyle uygulanmalıdır. Örneğin:

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

Ancak, oluşturma işlevinin dışındaki belirli bir grubun tüm köşeleri için dünya koordinatlarını bulmak istiyorsanız, muhtemelen bunu cpu'da yapmanız gerekir veya işi yapmak için OpenCL gibi bazı paralel programlama tekniklerini kullanmanız gerekir.GPU üzerinde.

En önemlisi, neden çizim prosedürünün dışında dünya koordinatları bilgisini istiyorsun? Sadece modelin dünya koordinatlarını bulmak istiyorsanız, sahnedeki her model için bir merkez koordinatı ayarlayabilir ve tüm örgü grubu yerine yalnızca o tek koordinatı izleyebilirsiniz.

Köşe bilgileri her zaman model koordinatlarında olmalı ve üzerinde herhangi bir değişiklik yapmak istemediğiniz sürece, dokunmadan köşe arabelleğinde saklanmalıdır.

2021-11-24 03:57:24

Birden çok grafiği bir araya getiriyorum. Bu nedenle, grafiklerin dönüşümlerini geçmek için üniforma kullanamıyorum, çünkü çizim çağrısı arasındaki dönüşümün üniformasını değiştiremeyeceğim. Ancak, ssbo'ları kullanmanın çok iyi bir alternatif olduğuna inanıyorum.
Christopher Barrios Agosto

Diğer dillerde

Bu sayfa diğer dillerde

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