Jump to content
  • Advertisement
Sign in to follow this  
Chris_F

mat3x3 array issue

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

If you intended to correct an error in the post then please contact us.

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);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
 
//example2
 
std::vector<glm::mat4> matrix(8192, glm::mat4(1.0f));
glNamedBufferStorageEXT(buffer, sizeof(matrix[0]) * matrix.size(), matrix.data(), 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);

Share this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!