shader storage buffer mat4x3[] array


#1

Hi I would like to reduce my memory footprint for my rendering pipeline.
A straightforward solution should be the use of 4x3 arrays to encode the modelmatrix, that is accessed indirectly.

My question is: does that work or is it prevented by some alignment or packing requirement that I am not aware of.

My problem is that as soon as I use 4x3 matrices, the transformation is wrong.


layout(std430, binding = 1) buffer TransformBuffer
{
	mat4x3 transformBuffer[];
};


...

mat4 M= mat4(transformBuffer[i]);


On CPU, I create the array, using glm constuctors:


for (auto & t : transforms) // glm::mat4
{ 
	smallerTransforms.push_back(glm::mat4x3(t));
}


Interestingly, If I bind the mat4 array and declare with mat4x3 in glsl, all is fine. So it appears to be some alignment problem, that I have no clue of.

GTX1070 btw.

Alignment works,
but the conversion is unexpected:



	mat4 M = mat4(	t.p[0], t.p[1], t.p[2], 0,
					t.p[3], t.p[4], t.p[5], 0,
					t.p[6], t.p[7], t.p[8], 0,
					t.p[9],	t.p[10], t.p[11],	1);


#2

mat4x3 has 4 columns and 3 rows (this is opposite to the usual mathematical convention, where a “4x3” or “four by three” matrix has 4 rows and 3 columns).

A column-major matrix is treated as an array of vectors, one for each column, so a column-major mat4x3 is equivalent to vec3[4]. In both std140 and std430 layouts, a vec3 is always aligned as a vec4, so an array of column-major mat4x3 has the same layout as an array of mat4x4.

If you want to save memory, you can declare the matrix as row-major. A row-major matrix is treated as an array of vectors, one for each row, so a row-major mat4x3 is equivalent to vec4[3], which doesn’t require any padding. But then you’d need to explicitly transpose the matrices on the client side.


#3

Take a look at:

Also, it’s useful to search the OpenGL forums when you have a question. Using Google for instance:"[noparse]mat4x3 site:opengl.org inurl:discussion_boards[/noparse]"