Ich verwende die struct mit den Lichparametern 3mal. Dieser Code funktioniert, aber das mit den 3 "uniform light? { ... }" gefällt mir nicht. Dazu habe ich mehreres probiert. Einmal oben bei layout, das wird nicht mal kompiliert. Und weiter unten die 3 ausgeklammerten Zeilen, dies wird kompiliert, aber mit glUniformBlockIndex nicht gefunden.
Gibt es da eine elegantere Lösung, oder muss ich es sein lassen ? Was ich machen könnte, ich könnte alle 3 Lichter in ein UBO nehmen, aber ich will es erst mal getrennt.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Layout gehört zum Uniform nicht zur Struct (die nicht GLSL spezifisch ist), kann man also z.B. so machen:
Code:
struct Light {
bool On;
vec3 Pos;
vec3 Color;
float CutOff;
};
layout (std140)uniform LightBlock {
Light lights[3];
};
void main()
{
for(int i =0; i <3; i++){
vec3 lColor = lights[i].Color;
}
...
}
Da der Uniform Block anonym ist kann man direkt auf die Member zugreifen.
Alternativ, z.B. wenn es mal viele Lichtquellen werden sollten, besser ein SSBO nutzen. UBOs bei NV sind max. 64k und auf AMD afaik seit einiger Zeit eh nur noch als SSBO emuliert (deshalb da keine Limitierung der Größe).
So wie ich es sehe, muss ich es einzeln machen, wie in meinen Post, wen ich für jede Lichtquelle ein eigener UBO will ? Dein Beispiel könnte ich nehmen, wen ich alle Lichtquellen in ein UBO packen will, dies wäre natürlich effizienter.
Zitat:
Alternativ, z.B. wenn es mal viele Lichtquellen werden sollten, besser ein SSBO nutzen. UBOs bei NV sind max. 64k und auf AMD afaik seit einiger Zeit eh nur noch als SSBO emuliert (deshalb da keine Limitierung der Größe).
Leider wird da mindestens OpenGL 4.3 verlangt, nur kann mein Intel-Chip nur 4.2 und für ein OpenGL 3.3 Tutorial, daher nicht brauchbar.
Aber interessant ist es trotzdem. So wie es aussieht, müsste man da auch keine Padding verwenden, um eine 16Byte Block zu füllen ? Wen UBO auf 64KB begrenzt ist, würden immerhin 1'000 Lichtquellen reinpassen ( 4 x 16 x 1'000 = 64'000 ). Oder kennst du ein Beispiel, in dem man an das 64KB-Limit kommt ?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
mathias hat geschrieben:
Wen UBO auf 64KB begrenzt ist, würden immerhin 1'000 Lichtquellen reinpassen ( 4 x 16 x 1'000 = 64'000 ). Oder kennst du ein Beispiel, in dem man an das 64KB-Limit kommt ?
Die Definition deiner Lichtquellen ist sehr simpel, für echte Lichtquellen benötigt man noch weitere Parameter, dann hat man pro Quelle schnell recht viele Bytes.
Und bei einem deferred oder forward clustered Renderer können das durchaus mehrere hunderte Lichtquellen sein die sichtbar sind, da wird das mit dem UBO knapp.
SSBOs haben den großen Vorteil dass man die im Compute Shader schreiben kann, und so dann auf der GPU z.B. Culling etc. machen kann.
Und bei einem deferred oder forward clustered Renderer können das durchaus mehrere hunderte Lichtquellen sein die sichtbar sind, da wird das mit dem UBO knapp.
Wen sie zu Laufzeit geändert werden müssen, dann ja. Wen es aber statische Lichtquellen sind, ZB Kandelaber , würde ich die Werte direkt in den Shader als Konstante reinkompilieren. Oder mache ich da einen Denkfehler ?
Registriert: So Aug 08, 2010 08:37 Beiträge: 460
Programmiersprache: C / C++ / Lua
Man macht halt immer das, was einem gerade gelegen kommt und wie es in den Speicher passt. Deine Idee mit dem "ich kompiliere die Lichtquelle statisch rein" ist halt unbrauchbar, wenn du Daten zur Laufzeit veraendern willst (weil shader neukompilieren doch etwas dauert), gds. aber brauchbar wenn die Daten halt statisch sind (aber mehr aufwand).
Ich persoenlich wuerde halt in 3.3 gar keine UBOs verwenden, sondern wenn ueberhaupt SSBOs (ueber extension vllt?) und ansonsten entweder "normal" uniform arrays nutzen oder den klassischen weg ueber texturen. Das ist sehr einfach zu implementieren und birgt den Vorteil, dass du wahrscheinlich nicht in Performancebegrenzer reinlaeufts. (imho der weg des geringsten widerstands = bester weg)
_________________ offizieller DGL Compliance Beauftragter Never run a changing system! (oder so)
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Ja. Du hast natürlich Recht, dass es keinen glUniformStruct() oder sowas gibt, mit dem man ein komplettes struct auf einen Schlag mit Werten belegen kann. Ich wollte nur klarstellen, dass man durchaus Index- und Elementzugriffsoperatoren (also [] und .) in glGetUniformLocation() verwenden darf. Du brauchst nicht zwinged UBOs, nur weil eine uniform-Variable ein struct ist.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: So Aug 08, 2010 08:37 Beiträge: 460
Programmiersprache: C / C++ / Lua
Das liegt daran, dass die Bloecke aufgesplittet werden und dann Material.foo[0] oder so heissen. Schau dir mal an wie das aussieht indem du mit glGetActiveUniform dir alle moeglichen Uniforms anzeigen laesst inklusive Namen. https://www.khronos.org/registry/OpenGL ... niform.xml
_________________ offizieller DGL Compliance Beauftragter Never run a changing system! (oder so)
Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.