mat3x3 array issue

This topic is 1767 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

When I try to upload a buffer of mat3x3s to a storage buffer, the matrices don't work.

layout(packed, binding = 0) readonly buffer matrix_buffer

{

mat3x3 matrix[];

};

...

gl_Position = vec4(vec3(pos, 0.0f) * matrix[gl_InstanceID], 1.0);
//doesn't work (nothing rendered)

gl_Position = vec4(vec3(pos, 0.0f) * mat3(1.0), 1.0);
//works


However, I have no issues when using mat4x4.

layout(packed, binding = 0) readonly buffer matrix_buffer

{

mat4x4 matrix[];

};

...

gl_Position = vec4(pos, 0.0f, 1.0) * matrix[gl_InstanceID];
//works


My GL code basically looks like this:

std::vector<glm::mat3> matrix(8192, glm::mat3(1.0f));
glNamedBufferStorageEXT(buffer, sizeof(matrix[0]) * matrix.size(), matrix.data(), 0);

//example2

std::vector<glm::mat4> matrix(8192, glm::mat4(1.0f));
glNamedBufferStorageEXT(buffer, sizeof(matrix[0]) * matrix.size(), matrix.data(), 0);


Share on other sites

I'm preeety sure "packed" layout can rearrange things in whatever way it wants. It could be realigning the 3x3 matrices in memory so they're more friendly for the GPU to access.

mat4 kinda don't have that issue since they're aligned already (GPU prefers chunks of 4 floats in sequence).

So you'll have to query the start and end of each matrix before updating them in the storage buffer. You could also try with std140 and std420 layouts, see if those work better. Granted, if you select a layout without memory alignment, they'll perform worse.

Share on other sites

I myself would layout an array of vec4 and construct matrix by its constructor from those vec4s, or, in case of matrix3x3 dilema (think wheather you do not need 3x4 matrix), I still believe mat3x3 should hold a constructor from naive array of float scalars, row or column.

Edited by JohnnyCode

Share on other sites

I have no experience with OpenGL 4+, so may be my knowledge is obsolete. The following is what I think:

1.) The standard layout for a 3x3 OpenGL matrix in memory, as long as row_major layout isn't used like in the OP, is

[ mc1r1 mc1r2 mc1r3 0 mc2r1 mc2r2 mc2r3 0 mc3r1 mc3r2 mc3r3 0 ]

But a vector of glm::mat3, as used in this line

std::vector<glm::mat3> matrix(8192, glm::mat3(1.0f));

probably has the zeros left out. I suspect the qualifier "packed" to not help here. You should debug and inspect matrix.data() for its content.

2.) If you use a 2D position and a 3x3 transform matrix, then I would assume that the 3rd co-ordinate is the homogeneous one. If you want it use that way, then this line

gl_Position = vec4(vec3(pos, 0.0f) * matrix[gl_InstanceID], 1.0);

need to be changed into this line

gl_Position = vec4(vec3(pos, 1.0f) * matrix[gl_InstanceID], 0.0).xywz;

or else translation will not work (please double check). The line computes a 3x1 by 3x3 transform, an reorders the result into a 4x1 homogeneous vector.

Edited by haegarr

Share on other sites

Since you see that GLSL forces a vec4 layout naturaly, you should literaly do old GLSL vec4 array to accomodate indexed matricies data. Like

uniform vec4 u_mats3[9];

this creates 36 floats that can hold 4 3x3 maticies.

To index a matrix and construct it

int index=i*X!!

mat3x3 m=mat3x3(vec3(),vec3(),vec3());

you have a problem

the solution is to use 4x3 matrix fastly indexed and created , or, using float u_[x] array. The first option is just better.in my opinion, since indexing a scalar array would require 8 additions instead of 2, and resulting data can be used both effectively the same, wehather 43x or 3x3.In the first case you do not create 4x3 matrix or can, still doing amount of operations that 3x3 matrix performs with 3d vector, not 4x

matrix with 4d vector

uniform vec4 u_mvecs[128]; // a vector is a raw, though fourth component is not used, or can be used for something else

int index=some*3;

vec3 vect=somevec;

vec3 transformedvector=vec3d( dot(u_mvecs[index],vect), dot(u_mvecs[index+1],vect), dot(u_mvecs[index+2],vect) );

or create a matrix if you reuse transformation and just index column of it (which you load raw like).

The memory of a 3like matrix up in your aplication will certainly not be aligned for fourth component but setting vec4 array by yourself can target this

Share on other sites

there is a typo. do not forget to append .xyz behid u_mvecs[index] , as u_mvecs[index] is a vec4 uniform vector

Share on other sites

The memory of a 3like matrix up in your aplication will certainly not be aligned for fourth component but setting vec4 array by yourself can target this

I would add to  this that you can find out wheather the matricies in yuor outer app are row or column major in memory by simply doing transformation like this

raw major:

vec3 transformedvector=vec3d( dot(u_mvecs[index].xyz,vect), dot(u_mvecs[index+1].xyz,vect), dot(u_mvecs[index+2].xyz,vect) );

column major:

vec3 transformedvector= u_mvecs[index].xyz*vect+ u_mvecs[index+1].xyz*vect+ u_mvecs[index+2].xyz*vect);

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 15
• 14
• 46
• Forum Statistics

• Total Topics
634059
• Total Posts
3015291
×