Three.js: No mat2/3/4 attribute support in shader

Created on 3 Apr 2019  路  7Comments  路  Source: mrdoob/three.js

Description of the problem

If I write attribute mat2/3/4 in shader and upload data like this

// glsl
attribute mat4 matrix;

// js
geometry.addAttribute( 'matrix', new THREE.BufferAttribute( data, 16 ) );

It fails because the second argument of gl.vertexAttribPointer() (= attribute.itemSize) takes only 1, 2, 3, or 4.

GL ERROR :GL_INVALID_VALUE : glVertexAttribPointer: size GL_INVALID_VALUE

I needed to break it up to columns to use them on Three.js.

// glsl
attribute vec4 column0;
attribute vec4 column1;
attribute vec4 column2;
attribute vec4 column3;

void main() {
    mat4 matrix = mat4( column0, column1, column2, column3 );
}

// js
geometry.addAttribute( 'column0', new THREE.BufferAttribute( data0, 4 ) );
geometry.addAttribute( 'column1', new THREE.BufferAttribute( data1, 4 ) );
geometry.addAttribute( 'column2', new THREE.BufferAttribute( data2, 4 ) );
geometry.addAttribute( 'column3', new THREE.BufferAttribute( data3, 4 ) );

So we can't practically use mat2/3/4 attribute in shader on Three.js because renderer doesn't handle them correctly. But I think allowing them may be useful.

To handle them we need to update WebGLRenderer to call enableAttribute and vertexAttribPointer multiple times for mat2/3/4.

https://stackoverflow.com/questions/38853096/webgl-how-to-bind-values-to-a-mat4-attribute

// glsl
attribute mat4 matrix;

// js
geometry.addAttribute( 'matrix', new THREE.BufferAttribute( data, 16 ) );

// js in renderer
state.enableAttribute( programAttribute.location );
state.enableAttribute( programAttribute.location + 1 );
state.enableAttribute( programAttribute.location + 2 );
state.enableAttribute( programAttribute.location + 3 );
_gl.vertexAttribPointer( programAttribute.location, 4, type, normalized, 64, 0 );
_gl.vertexAttribPointer( programAttribute.location + 1, 4, type, normalized, 64, 16 );
_gl.vertexAttribPointer( programAttribute.location + 2, 4, type, normalized, 64, 32 );
_gl.vertexAttribPointer( programAttribute.location + 3, 4, type, normalized, 64, 48 );
Three.js version
  • [x] Dev
  • [ ] r103
  • [ ] ...
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)
Enhancement

Most helpful comment

My use case is geometry instancing. I want to pass local model matrix for each instance.

https://github.com/takahirox/three.js/blob/PhysicsInstancing/examples/webgl_physics_instancing.html#L247

All 7 comments

But I think enabling attribute mat2/3/4 may be useful.

What is your use case?

And why do we need to support something WegGL does not?

Users pass vectors or quaternions instead, in this case, I expect. More efficient.

My use case is geometry instancing. I want to pass local model matrix for each instance.

https://github.com/takahirox/three.js/blob/PhysicsInstancing/examples/webgl_physics_instancing.html#L247

Position + quaternion (and univariate scale factor if needed) is more efficient than a Matrix4 -- at least as far as passing the data is concerned.

I think your use case is sufficiently-compelling, however.

Given you want to support something WebGL does not, I suggest you at least consider the alternatives.

Given you want to support something WebGL does not, I suggest you at least consider the alternatives.

WebGL support mat2/3/4 attribute in vertex shader.
I think we can add some simple utility functions in three like this:

// pseudocode
state.enableAttribute = function(){
    if (gl.getActiveAttrib(program, i).type === gl.FLOAT_MAT2) {
        for(let i = 0;i < Math.sqrt(matSize);i ++) {
            gl.enableAttribute(location + i);
        }
    }
};

Yes, I think WebGL GLSL supports mat2/3/4 attributes. So @WestLangley could you explain what "WebGL doesn't support mat2/3/4 attribues" means here for me?

@takahirox Sorry, I'm not sure what I was thinking... :/

No problem. I think because I wrote the issue comment poorly then you misunderstood something. I updated the comment a bit. I hope the issue is clearer now.

Was this page helpful?
0 / 5 - 0 ratings