
Uniform Buffer Layout question
Posted Friday, 28 May, 2010 - 19:35 by sgsrules inHi, i've started using uniform buffer objects and have everything work right.... for the most part. It seems my layout is a bit fudged up for example if i have the following c# structure
public struct LightProperties { public Vector3 Position; public Vector3 Ambient; public Vector3 Diffuse; public Vector3 Specular; } LightProperties Light; Light.Position = new Vector3(0,0,0); Light.Ambient = new Vector3(1,1,1); Light.Diffuse = new Vector3(1, 1, 1); Light.Specular = new Vector3(1, 1, 1);
and pass the following in my shader
layout(std140) uniform lightProperties { vec3 pos; vec3 amb; vec3 dif; vec3 spec; }
for some reason things don't get mapped right what i get in the shader is the following:
pos = Position.X,Position.Y,Position.Z; //as it should
amb = 0,Ambient.r,Ambient.g; // wrong offset by one
dif = Ambient.b,0,Diffuse.r; // wrong again offset even more
spec = Diffuse.g, Diffuse.b,0; // wrong again
It looks like it's passing the Vector3 as Vector4 in fact if i change my struct to
public struct LightProperties { public Vector4 Position; public Vector4 Ambient; public Vector4 Diffuse; public Vector4 Specular; }
and leave my shader code as is things seem to work as they should. but i don't want to spend the extra resources passing vector4 when i only need vector3. I'm updating my uniform buffer with the following code:
GL.BindBuffer(BufferTarget.UniformBuffer, lightPropertiesBuf[0]); GL.BufferData(BufferTarget.UniformBuffer, (IntPtr)Marshal.SizeOf(Light), ref Light, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.UniformBuffer, 0);


Comments
Re: Uniform Buffer Layout question
There is a layout mismatch. I don't know if it is caused by .Net or the uniform buffer layout (check the specs), but you can control the layout on .Net using StructLayoutAttribute (try Pack=1 or Pack=16 depending on what the uniform buffer expects).
Re: Uniform Buffer Layout question
Thanks for the quick reply, I had already tried using StructLayoutAttribute which didn't change anything. But i did go back and look at the spec for std140 and it states:
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.
so basically any vector3 are passed as as vec4. I guess i'll just use the extra space for something else.