DGL
https://delphigl.com/forum/

UBO und vec3
https://delphigl.com/forum/viewtopic.php?f=20&t=11635
Seite 1 von 2

Autor:  mathias [ Sa Mär 10, 2018 21:57 ]
Betreff des Beitrags:  UBO und vec3

Kann es sein, das UBO mit vec3 Probleme macht ?

Die Variante mit vec4 geht, aber die mit vec3 kommen falsche Parameter beim Shader an.

Code:
  1. //layout (std140) uniform Material {
  2. //  vec3 Mambient;    // Umgebungslicht
  3. //  vec3 Mdiffuse;    // Farbe
  4. //  vec3 Mspecular;   // Spiegelnd
  5. //  float Mshininess; // Glanz
  6. //};
  7. //
  8. layout (std140) uniform Material {
  9.   vec4 Mambient;    // Umgebungslicht
  10.   vec4 Mdiffuse;    // Farbe
  11.   vec4 Mspecular;   // Spiegelnd
  12.   float Mshininess; // Glanz
  13. };


Lazarus Seitig habe ich es auch angepasst.
Code:
  1. type
  2.   TMaterial = record
  3.     ambient,      
  4.     diffuse,        
  5.     specular: TVector4f; //  Auf TVector3f geändert.
  6.     shininess: GLfloat;  
  7.   end;


Das einzige was mit vec3 beim shader richtig ankommt, ist ambient.
Ich habe es ach mit "packed record" probiert, bringt auch nichts,
Was habe ich übersehen ?

Hier habe ich die Source: https://github.com/sechshelme/Lazarus-OpenGL-3.3-Tutorial/tree/master/08_-_Material_Eigenschaften/10_-_Uniform_Buffer_Object_(UBO)

Autor:  end [ So Mär 11, 2018 11:36 ]
Betreff des Beitrags:  Re: UBO und vec3

Lies dir Mal in der glsl spec durch sie alignment bei ubos funktioniert.

TL;Dr: die Dinger sind vec4 alignt. Folglich musst du entweder ein Union nehmen, wenn du das so verwenden willst, oder einfach vec4.
Kannst auch mit floats padden oder einfach das memcpy selber bauen.

(Tbh nimm einfach vec4 in deiner Datenstruktur)

Autor:  mathias [ So Mär 11, 2018 17:41 ]
Betreff des Beitrags:  Re: UBO und vec3

So würde es funktionieren.
Oder sollte man im Shader auch mit Dummys auf vec4 aufrunden ?
Code:
  1. layout (std140) uniform Material {
  2.   float Mshininess; // Glanz
  3.   vec3 Mambient;    // Umgebungslicht
  4.   vec3 Mdiffuse;    // Farbe
  5.   vec3 Mspecular;   // Spiegelnd
  6. };


Code:
  1. type
  2.   TMaterial = record
  3.     shininess: GLfloat;             // Glanz
  4.     dummy: array[0..2] of GLfloat;
  5.     ambient: TVector3f;             // Umgebungslicht
  6.     d1: GLfloat;
  7.     diffuse: TVector3f;             // Farbe
  8.     d2: GLfloat;
  9.     specular: TVector3f;            // Spiegelnd
  10.     d3: GLfloat;
  11.   end; 


Aber ich denke, die sauberste Lösung wird sein, vec4 zu übergeben, und den 4. Wert zu ignorieren.

Zum Teil gibt es schon Sachen in OpenGL, die recht unlogisch erscheinen. :roll:

Autor:  end [ So Mär 11, 2018 19:11 ]
Betreff des Beitrags:  Re: UBO und vec3

es ist halt nicht unlogisch, weil das ganze auf hw ebene sich dann signifikant besser optimieren laesst.

u.a. die caches sind halt darauf optimiert immer mit 16 byte alignten daten zu arbeiten -> schneller

Autor:  mathias [ So Mär 11, 2018 22:30 ]
Betreff des Beitrags:  Re: UBO und vec3

Zitat:
u.a. die caches sind halt darauf optimiert immer mit 16 byte alignten daten zu arbeiten -> schneller

Das wird wohl etwa der gleiche Effekt sein, wie die Word-Ausrichtung von Bytes auf einer 16-Bit CPU ?
Sehe ich das Richtig, das bei einer normalen Uniformübergabe, ein float gleich viel Zeit braucht, wie ein vec4 ?

Zitat:
Oder sollte man im Shader auch mit Dummys auf vec4 aufrunden ?
Was meinst du zu dieser Frage ?

Autor:  TAK2004 [ Mo Mär 12, 2018 16:35 ]
Betreff des Beitrags:  Re: UBO und vec3

Da die Operationen auf vec4 laufen, würde mindestens eine zusätzliche Operationen zum füllen der 4. Komponente benötigt werden, da nicht jede Operationen die ignorieren kann.
Aber hier gehts mehr um cache alignment, cache effizienz.
Da vec3f 16Byte aligned ist, müsste für das auslesen von diffuse erst 16byte geladen werden, 12 verworfen und dann nochmal 16byte geladen, 4 verworfen und dann noch shiften und verunden.
Passt das ganze nicht dauerhaft in die register, weil die Funktion zuviele Register braucht, macht er das immer wieder.
Das wäre super kostenintensiv und hätte 0 mehrwert.
So zwingt man den Nutzer einfach 4byte zu verschwenden oder da noch was rein zu quetschen und benötigt keine weiteren Operationen.
Das hätte ich auch beim Swizzle begrüsst, wenn man von einem Pixelformat in das Zielformat hochladen kann und im Shader nur noch das eine Format hat.

Autor:  mathias [ Mo Mär 12, 2018 18:14 ]
Betreff des Beitrags:  Re: UBO und vec3

Wen ich es richtig verstehe, macht der Shader aus jeder Variable, egal ob byte, float oder vecx, einen 16Byte-Block, dies braucht zwar mehr Speicher, aber dafür ist es um einiges schneller ?
Betrifft dies nur die Unifom-Blöcke, oder generell alle Variablen im GLSL-Code ?

Autor:  TAK2004 [ Mo Mär 12, 2018 19:21 ]
Betreff des Beitrags:  Re: UBO und vec3

So einfach ist es nicht. Die Rechenwerke laden aus dem Speicher Cachelines, egal welcher Typ.
Hier geht es um die größe der Variable und wie sie in einem Register liegt. Vec liegt 16byte aligned im register, da die rechenbefehle die so brauchen. Der Shader muss also anfangen hin und her zu kopieren, verunden und shiften, damit es passt, wenn die nicht passend kommen.

Autor:  mathias [ Mi Mär 14, 2018 20:05 ]
Betreff des Beitrags:  Re: UBO und vec3

mathias hat geschrieben:
So würde es funktionieren.
Oder sollte man im Shader auch mit Dummys auf vec4 aufrunden ?
Code:
  1. layout (std140) uniform Material {
  2.   float Mshininess; // Glanz
  3.   vec3 Mambient;    // Umgebungslicht
  4.   vec3 Mdiffuse;    // Farbe
  5.   vec3 Mspecular;   // Spiegelnd
  6. };


Code:
  1. type
  2.   TMaterial = record
  3.     shininess: GLfloat;             // Glanz
  4.     dummy: array[0..2] of GLfloat;
  5.     ambient: TVector3f;             // Umgebungslicht
  6.     d1: GLfloat;
  7.     diffuse: TVector3f;             // Farbe
  8.     d2: GLfloat;
  9.     specular: TVector3f;            // Spiegelnd
  10.     d3: GLfloat;
  11.   end; 


Aber ich denke, die sauberste Lösung wird sein, vec4 zu übergeben, und den 4. Wert zu ignorieren.

Zum Teil gibt es schon Sachen in OpenGL, die recht unlogisch erscheinen. :roll:


Kann ich es im Tutorial so machen, oder ist es nicht zu empfehlen ?

Autor:  TAK2004 [ Do Mär 15, 2018 09:20 ]
Betreff des Beitrags:  Re: UBO und vec3

Ja so kannst du es machen. Ich empfehle dann dummy zu padding1 bis n umzubenennen.
Alternative kannst du auch für TVector3f ein byte alignment von 16Byte einstellen und die dummy‘s weg lassen aber dann verbraucht es in Containern auch entsprechend die 4 byte und es kann sein, dass du das lesen der daten mit dem Typ machst, dann würde dies nicht mehr funktionieren. Von daher musst du gucken was besser passt.
Microsoft hat in ihren structs immer pad0-n, padding0-n oder reserved0-n.

Autor:  mathias [ Do Mär 15, 2018 18:35 ]
Betreff des Beitrags:  Re: UBO und vec3

Zitat:
Alternative kannst du auch für TVector3f ein byte alignment von 16Byte einstellen

Ich verstehe nicht was du damit meinst. :roll:

Zitat:
Ja so kannst du es machen. Ich empfehle dann dummy zu padding1 bis n umzubenennen.

Das mit dem padding, werde ich anpassen, wäre es nicht bessert, wen man mit pad0 anstelle von pad1 beginnt ?

Autor:  TAK2004 [ Do Mär 15, 2018 18:41 ]
Betreff des Beitrags:  Re: UBO und vec3

https://www.freepascal.org/docs-html/3.0.2/prog/progsu1.html <- byte alignment of records

Ich hatte es 1-n genannt, weil du mit 1 im Beispiel gezählt hast. Ich mag auch lieber mit 0 anfangen.

Autor:  mathias [ Do Mär 15, 2018 18:51 ]
Betreff des Beitrags:  Re: UBO und vec3

Zitat:
https://www.freepascal.org/docs-html/3.0.2/prog/progsu1.html <- byte alignment of records
Genau dies wollte, ich probieren, aber es funktioniert nicht.
Aber ich wollte es beim ganzen Record machen und nicht beim einzelnen TVector3f, da dieser auch anders wertig gebraucht wird.

Aus diesem Grund habe ich dort gerade ein Post geschrieben.
http://www.lazarusforum.de/viewtopic.php?f=10&t=11502

Autor:  mathias [ Do Mär 15, 2018 23:12 ]
Betreff des Beitrags:  Re: UBO und vec3

Jetzt verstehe ich dies langsam mit den reinquetschen.
Ich habe jetzt hinter "ambient" noch "shininess" gesetzt, somit kommt die auch auf 16Byte.
Somit wird die Mesh auch richtig dargestellt.

Code:
  1. type
  2.   TMaterial = record
  3.     ambient: TVector3f;             // Umgebungslicht
  4.     shininess: GLfloat;             // Glanz
  5.     diffuse: TVector3f;             // Farbe
  6.     pad2: GLfloat;
  7.     specular: TVector3f;            // Spiegelnd
  8.     pad3: GLfloat;
  9.   end;


Code:
  1. layout (std140) uniform Material {
  2.   vec3 Mambient;    // Umgebungslicht
  3.   float Mshininess; // Glanz
  4.   vec3 Mdiffuse;    // Farbe
  5.   vec3 Mspecular;   // Spiegelnd
  6. };



Aber etwas verstehe ich immer noch nicht.
Ich habe noch einer Array eingebaut, welche, welche 20Byte Gross ist.
Müsste es diese nicht auch 32Byte aufrunden ?
Ich habe Pascal-Seitig dafür 32Byte mit test reserviert.
Code:
  1. layout (std140) uniform Material {
  2.   float test[5]; // Als Versuch
  3.  
  4.   vec3 Mambient;    // Umgebungslicht
  5.   float Mshininess; // Glanz
  6.   vec3 Mdiffuse;    // Farbe
  7.   vec3 Mspecular;   // Spiegelnd
  8. };


Code:
  1.   TMaterial = record
  2.     test: array[0..7] of GLfloat;
  3.  
  4.     ambient: TVector3f;             // Umgebungslicht
  5.     shininess: GLfloat;             // Glanz
  6.     diffuse: TVector3f;             // Farbe
  7.     pad2: GLfloat;
  8.     specular: TVector3f;            // Spiegelnd
  9.     pad3: GLfloat;
  10.   end;


PS: Jetzt sehe ich es, für jeden Float in der Array werden 16Byte gebraucht.
So funktioniert es.
Code:
  1.   TMaterial = record
  2.     test: array[0..4, 0..3] of GLfloat;

Autor:  mathias [ Fr Mär 16, 2018 20:16 ]
Betreff des Beitrags:  Re: UBO und vec3

Etwas ist aber immer noch unlogisch.
Wieso wird für jeden Float in der Array 16Byte gebraucht.

Code:
  1. layout (std140) uniform Material {
  2.   float test[5];
  3.  
  4.   vec3 Mambient;    // Umgebungslicht
  5.   float Mshininess; // Glanz
  6.   vec3 Mdiffuse;    // Farbe
  7.   vec3 Mspecular;   // Spiegelnd
  8. };  


Code:
  1. type
  2.   TMaterial = record
  3.     test: array[0..4, 0..3] of GLfloat; // ( 5x4x4 = 80 )
  4.  
  5.     ambient: TVector3f;             // Umgebungslicht
  6.     shininess: GLfloat;             // Glanz
  7.     diffuse: TVector3f;             // Farbe
  8.     pad2: GLfloat;
  9.     specular: TVector3f;            // Spiegelnd
  10.     pad3: GLfloat;
  11.   end;


Definiere ich aber die Float einzeln, dann wird wie erwartet 32Byte gebraucht. ( 2x16 )

Code:
  1. layout (std140) uniform Material {
  2.   float t0;
  3.   float t1;
  4.   float t2;
  5.   float t3;
  6.   float t4;
  7. ...


Code:
  1. type
  2.   TMaterial = record
  3.     test: array[0..7] of GLfloat; // ( 8x4 = 32 )
  4. ...

Seite 1 von 2 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/