【问题标题】:mat4 type in attribute shader属性着色器中的mat4类型
【发布时间】:2026-01-16 11:15:02
【问题描述】:

如何发送到 MAT4 类型的着色器属性?

attribute mat4 attr;
...

JS:

var attr=gl.getAttribLocation(_program,"attr");

【问题讨论】:

    标签: opengl-es webgl shader


    【解决方案1】:

    From the spec 第 2.10.4 节

    当一个属性变量被声明为mat4,它的 矩阵列取自通用属性 i 的 (x, y, z, w) 组件 通过 i + 3.

    所以

    JS:

    var row0Location = gl.getAttribLocation(_program, "attr");
    var row1Location = row0Location + 1;
    var row2Location = row0Location + 2;
    var row3Location = row0Location + 3; 
    

    至于获取数据,最常见的方法是将所有矩阵放在一个缓冲区中

    var matrices = new Float32Array(numMatrices * 16);
    
    ... // fill out your matrices
    
    gl.bufferData(gl.ARRAY_BUFFER, matrices, gl.STATIC_DRAW);
    

    然后设置属性

    var floatsPerRow = 4
    var bytesPerRow = floatsPerRow * 4;
    var bytesPerMatrix = bytesPerRow * 4;
    var row0Offset = bytesPerRow * 0;
    var row1Offset = bytesPerRow * 1;
    var row2Offset = bytesPerRow * 2;
    var row3Offset = bytesPerRow * 3;
    gl.enableVertexAttribArray(row0Location);
    gl.vertexAttribPointer(row0Location, floatsPerRow, gl.FLOAT, 
                           false, bytesPerMatrix, row0Offset);
    gl.enableVertexAttribArray(row1Location);
    gl.vertexAttribPointer(row1Location, floatsPerRow, gl.FLOAT, 
                           false, bytesPerMatrix, row1Offset);
    gl.enableVertexAttribArray(row2Location);
    gl.vertexAttribPointer(row2Location, floatsPerRow, gl.FLOAT, 
                           false, bytesPerMatrix, row2Offset);
    gl.enableVertexAttribArray(row3Location);
    gl.vertexAttribPointer(row3Location, floatsPerRow, gl.FLOAT, 
                           false, bytesPerMatrix, row3Offset);
    

    需要注意的事项。如果您正在调试并且在着色器中注释掉attr,那么row0Location 将是-1,并且使用-1 位置调用所有gl.vertexAttrib 函数是无操作的,这很好。但是,因为您计算了其他位置 row1Locationrow2Locationrow3Location 就 WebGL 而言将是有效的属性位置,但就您的程序而言是无效的。没什么大不了的,只是需要牢记。

    【讨论】:

    • 这取决于您的数据。查看答案