Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

21

28.06.2014, 14:00

Nun ja, ich glaube, ich stelle Texturen erstmal hinten an, die düften sich später wahrscheinlich von selbst klären. Meine wahrscheinlcih letzte Frage betrifft Uniforms. Ich habe mir mal Uniform-Buffers und -Blocks angeschaut, aber ich bin mir nicht sicher, wie man das genau handhabt. Haben die Uniform-Blöcke bei dir zum Beispiel ein fest vorgeschriebenes Format? Und wie genau greifst du hier wieder auf die einzelnen Elemente zu, haben diese vorgeschriebene Namen? Denn die Indices der Uniforms im Block können anscheinend ja nicht mit einem layout versehen werden. Wie also werden hier die Locations bestimmt? Mir fallen momentan dann doch wieder "nur" festgeschriebene Namen ein.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

22

28.06.2014, 14:20

Die Inhalte von Uniform Buffern haben ebenfalls keine wirklichen Locations im engeren Sinn. Es sind halt Buffer. Der Shader muss nur auf die richtige Stelle im Buffer zugreifen um an die Daten zu kommen. Deshalb musst du ein Memorylayout festlegen. Das definiert, an welcher Stelle dann welche Daten kommen müssen. Dabei gibt es Layouts bei denen du OpenGL fragen musst, an welches Byteoffset welche Daten kommen und es gibt Layouts, bei denen OpenGL feste Regeln definiert, die du dann einhalten kannst und direkt an die entsprechenden Stellen in den Buffer schreiben kannst, ohne diese vorher zur Laufzeit zu erfragen. Für genauere Informationen schau mal ins OpenGL Wiki, da steht alles beschrieben...
http://www.opengl.org/wiki/Uniform_Buffer_Object

Ich würde normalerweise "std140" verwenden um nicht vorher erfragen zu müssen.
http://ptgmedia.pearsoncmg.com/images/97…552628_AppL.pdf

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (28.06.2014, 14:25)


23

28.06.2014, 14:46

D.h. wenn ich einen solchen Uniform Buffer habe:

C-/C++-Quelltext

1
2
3
4
5
6
layout (std140) uniform Transforms
{
    mat4 World;
    mat4 View;
    mat4 Projection;
};


Dann kann ich die Offsets berechnen (danke für Appendix L an dieser Stelle). Allerdings muss ich eben festlegen, dass der Block immer den Namen "Transforms" tragen muss, damit der Block-Index gefunden werden kann. Richtig soweit?

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

24

28.06.2014, 14:58

Ja.
"World" sollte bei 0 anfangen, "View" beim 64. Byte und "Projection" bei 128. Du musst nur auch noch aufpassen wegen Row Major und Column Major. Das kann man auch mit "layout" spezifizieren wie im Wiki ja schon steht.

Ach, ja. Übrigens: Ich halte es für ziemlich uneffizient die drei einzelnen Matrizen bei jeden einzelnen Vertex im Shader zu multiplizieren. Mindestens "Projection" und "View" kann man im voraus in einziges mal auf der CPU multiplizieren und wenn man keine Weltkoordinaten braucht, auch gleich alles und eine "ModelViewProjection"-Matrix anlegen.

25

28.06.2014, 15:01

Danke für den Hinweis. Also gut. Ist es dann aber nicht effizienter alle Uniforms direkt in einen einzelnen Block zu "quetschen"? Allerdings ist das schon etwas unansehnlich.


Wenn ich das richtig verstanden habe, werden vec3-Uniforms immer auf 4 * Datentyp gepaddet. Sollte ich also ein Array von vec3s haben (Beispielsweise drei-dimensionale Textur-Koordinaten) dann muss ich das Array im Endeffekt wie eines aus vec4s behandeln, oder?

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

26

28.06.2014, 15:08

In der Regel, denke ich schon das es effizienter ist. Ich finde es eigentlich einfacher als 1000 Uniforms per Hand zu setzen. Wenn du einige Werte hast, die sich für den gesamten Renderdurchgang nicht ändern(Eine "ViewProjection"-Matrix zum Beispiel...), könnte es möglicherweise vielleicht Sinn machen, diese in einen eigenen Block zu packen und dann nicht mehr anzufassen. Und ein anderer Block eben mit Werten die dauernd angepasst werden müssen. Performancemessungen habe ich da noch nicht gemacht.

Ja das mit den Vec4 stimmt. Das musst du machen. Manchmal findet man einen anderen Verwendungszweck für den freien Wert und kann gleich Vec4 nehmen.

27

29.06.2014, 19:34

So, uniform Buffer scheinen mich nicht wirklich zu mögen. Der folgende Shader kompiliert nicht auf dem aktuellsten fglrx-Treiber von AMD/ATI:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#version 330

layout(location=0) in vec3 aPosition;
layout(location=5) in vec2 aTexCoord;
layout(location=4) in vec4 aColor;

out vec2 vTexCoord;
out vec4 vColor;

layout(std140) uniform Transforms
{
    mat4 World;
    mat4 ProjectionView;
};

void main(void)
{
    vTexCoord = aTexCoord;
    vColor = aColor;
    gl_Position = Transforms.ProjectionView * Transforms.World * vec4(aPosition.xyz, 1.0);
}


Ausgabe ist folgende:

Quellcode

1
2
3
4
5
[Shader] > Compilation failed: Vertex shader failed to compile with the following errors:
ERROR: 0:21: error(#143) Undeclared identifier: Transforms
ERROR: 0:21: error(#222) Illegal vector field selection: ProjectionView
ERROR: 0:21: error(#222) Illegal vector field selection: World
ERROR: error(#273) 3 compilation errors.  No code generated


Ist das ein Treiber-Bug oder mache ich irgendetwas falsch? Also OpenGL-Version nutze ich natürlich OpenGL 3.3.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

28

30.06.2014, 00:48

Ich musste den Shader jetzt auch gerade mal Testen um darauf zu kommen.
Ah, gemeiner Fehler. Ist mir auch schon passiert:
Ein Uniform Block ist keine Struktur, Namensraum etc. man muss dessen Namen beim Zugriff also nicht nennen...

HLSL-Quelltext

1
gl_Position = ProjectionView * World * vec4(aPosition.xyz, 1.0);

29

30.06.2014, 15:56

Ah, ist das gemein! Das steht glaube ich nicht mal im Standard, denn den habe ich auch schon durchgeblättert!
Danke dir! :thumbsup:

Aber wofür gibt es die Named-Uniform-Blocks dann überhaupt?! Nur zur Identifikation?

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

30

30.06.2014, 16:02

Scheinbar hauptsächlich zur Identifikation im Hauptprogramm.
Ich habe gerade nachgelesen, dass man, wenn man möchte, dem Uniform Blocks scheinbar doch auch Namen für die Verwendung in GLSL geben kann, siehe hier:
http://www.opengl.org/wiki/Interface_Block_(GLSL)#Syntax ("instance_name" in dem Beispiele)

Werbeanzeige