Opengl Uniform Buffers

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
foofel
Beiträge: 10
Registriert: 03.03.2014, 12:34

Opengl Uniform Buffers

Beitrag von foofel »

Hey, ich versuche gerade eine liste aus structs in einem shader zu updaten, leider bin ich wohl zu doof fürs padding.

das struct sieht so aus:

Code: Alles auswählen

struct PointLight
{
    glm::vec2 pos;
    glm::vec3 color;
    float _pad1;
    float intensity;
    float _pad2;
}; 

struct LightList
{
    PointLight lights[2];
    float numLights;
};
in glsl ist die definition:

Code: Alles auswählen

#define MAX_NUM_TOTAL_LIGHTS 2
struct PointLight {
	vec2 pos;
	vec3 color;
	float intensity;
};

layout (std140) 
uniform LightList {
	PointLight light[MAX_NUM_TOTAL_LIGHTS];
	float numLights;
} lights;
numLights kommt richtig an, aber die werte im pointLight nicht. Wenn ich im pointlight alle variablen auf vec4 änder geht es. Daher nehme ich an das es das alignment sein muss was ich wohl noch verkacke. Guck ich mir den buffer per nsight an sieht der auch richtig aus, also die daten sind da. Jemand ne idee?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Opengl Uniform Buffers

Beitrag von Schrompf »

Idee: layout (std140) muss auch oben an die Deklaration der Struktur PointLight. Außerdem müsstest Du dann noch zweimal float Padding nach PointLight::pos einfügen, glaube ich.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
foofel
Beiträge: 10
Registriert: 03.03.2014, 12:34

Re: Opengl Uniform Buffers

Beitrag von foofel »

Hab ne lösung die geht:

Code: Alles auswählen

	struct PointLight
	{
		glm::vec3 color;
		float intensity;
		glm::vec2 pos;
		float pad[2];
	}; 
und halt

Code: Alles auswählen

struct PointLight {
	vec3 color;
	float intensity;
	vec2 pos;
};

layout (std140) 
uniform LightList {
	PointLight light[MAX_NUM_TOTAL_LIGHTS];
	float numLights;
} lights;
ich kann mir zwar aus den specs irgendwas aus den fingern saugen wieso das jetzt geht aber so richtig glücklich bin ich mit der antwort nicht. das hätte ich nämlich beim vorherigen auch gekonnt... :D Ich finde die regeln lesen sich ziemlich kompliziert. Vielleicht muss man das aber auch nur mal genauer durchgehen. Für Interessierte:

Code: Alles auswählen

	1. If the member is a scalar consuming N basic machine units, the base alignment is N.
	2. If the member is a two- or four-component vector with components consuming N basic machine units, the base alignment is 2N or 4N, respectively.
	3. If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
	4. If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The array may have padding at the end; the base offset of the member following the array is rounded up to the next multiple of the base alignment.
	5. If the member is a column-major matrix with C columns and R rows, the matrix is stored identically to an array of C column vectors with R components each, according to rule (4).
	6. If the member is an array of S column-major matrices with C columns and R rows, the matrix is stored identically to a row of S C column vectors with R components each, according to rule (4).
	7. If the member is a row-major matrix with C columns and R rows, the matrix is stored identically to an array of R row vectors with C components each, according to rule (4).
	8. If the member is an array of S row-major matrices with C columns and R rows, the matrix is stored identically to a row of S R row vectors with C components each, according to rule (4).
	9. If the member is a structure, the base alignment of the structure is N, where N is the largest base alignment value of any of its members, and rounded up to the base alignment of a vec4. The individual members of this substructure are then assigned offsets by applying this set of rules recursively, where the base offset of the first member of the sub-structure is equal to the aligned offset of the structure. The structure may have padding at the end; the base offset of the member following the sub-structure is rounded up to the next multiple of the base alignment of the structure.
	10. If the member is an array of S structures, the S elements of the array are laid out in order, according to rule (9).
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Opengl Uniform Buffers

Beitrag von Schrompf »

Das ist halt alles super-abstraktes Bla, was eigentlich nur sagen will, dass der GPU-Konstantenspeicher in Einheiten von 4xfloat organisiert ist. In Deiner ersten Struktur PointLight ist pos halt in .xy des ersten Konstantenregisters gelandet. Blieb .zw übrig, aber das reicht nicht mehr für vec3 color. Also wurde zweimal float Padding eingeführt und das zweite Konstantenregister angerissen für color. float intensity passte dann als skalarer Wert noch stressfrei hinten in .w des zweiten Registers rein.

Und Deine neue Struktur gruppiert halt die Member schön so, dass sie jeweils ganze 4er-Gruppen ergeben. Daher geht's damit.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Antworten