我有这个变量'xformMatrix',每个元素都包含16个值的数组:
var xformMatrix =
[[0.9238795325112867, 0.3826834323650898, 0.0,
-0.3826834323650898, 0.9238795325112867, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0],
[0.7071067811865476, 0.7071067811865475, 0.0, 0.0,
-0.7071067811865475, 0.7071067811865476, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0],
[0.38268343236508984, 0.9238795325112867, 0.0, 0.0,
-0.9238795325112867, 0.38268343236508984, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0],
[6.123233995736766e-17, 1, 0.0, 0.0,
-1, 6.123233995736766e-17, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0]]
我正在尝试使用4x4矩阵作为属性来旋转我的三角形,而不必填充其顶点数组。我相信我对gl.vertexAttribPointer要求的尺寸感到困惑:
gl.vertexAttribPointer(a_xformMatrix, 1, gl.FLOAT, false, 6 *
Float32Array.BYTES_PER_ELEMENT, 5 * Float32Array.BYTES_PER_ELEMENT);
这是我的着色器的设置方式:
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute mat4 a_xformMatrix;\n' +
'attribute vec3 a_Color;\n' +
'varying vec3 v_Color;\n' +
'void main() {\n' +
' v_Color = a_Color;\n' +
' gl_Position = a_xformMatrix * a_Position;\n' +
'}\n';
// Fragment shader program
var FSHADER_SOURCE =
'precision mediump float;\n' +
'varying vec3 v_Color;\n' +
'void main() {\n' +
' gl_FragColor = vec4(v_Color, 1.0);\n' +
'}\n';
我的功能示例:
function initVertexBuffers(gl) {
// Triangle Verticies
var vertices = new Float32Array(
[ // x, y r, g, b rotate matrix
0.0, 0.5, 1.0, 0.0, 0.0, xformMatrix[0],
-0.5, -0.5, 1.0, 0.0, 0.0, xformMatrix[0],
0.5, -0.5, 1.0, 0.0, 0.0, xformMatrix[0],
0.0, 0.5, 0.0, 1.0, 0.0, xformMatrix[1],
-0.5, -0.5, 0.0, 1.0, 0.0, xformMatrix[1],
0.5, -0.5, 0.0, 1.0, 0.0, xformMatrix[1],
0.0, 0.5, 0.0, 0.0, 1.0, xformMatrix[2],
-0.5, -0.5, 0.0, 0.0, 1.0, xformMatrix[2],
0.5, -0.5, 0.0, 0.0, 1.0, xformMatrix[2],
0.0, 0.5, 1.0, 0.0, 1.0, xformMatrix[3],
-0.5, -0.5, 1.0, 0.0, 1.0, xformMatrix[3],
0.5, -0.5, 1.0, 0.0, 1.0, xformMatrix[3]
]);
var n = 12; // The number of vertices
// Create a buffer object
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log('Failed to create the buffer object');
return false;
}
// Bind the buffer object to target
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// Write date into the buffer object
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Assign the buffer object to the position attribute variable
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
// Assign the buffer object to the color attribute variable
var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
if (a_Color < 0) {
console.log('Failed to get the storage location of a_Color');
return -1;
}
// Assign the buffer object to the rotation matrix attribute variable
var a_xformMatrix = gl.getAttribLocation(gl.program, 'a_xformMatrix');
if (a_xformMatrix < 0) {
console.log('Failed to get the storage location of a_xformMatrix');
return -1;
}
// Set Pointers
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(a_xformMatrix, 1, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 5 * Float32Array.BYTES_PER_ELEMENT);
// Enable the assignment to a_Position variable
gl.enableVertexAttribArray(a_Position);
gl.enableVertexAttribArray(a_Color);
gl.enableVertexAttribArray(a_xformMatrix);
return n;
}
最终输出应如下所示:
这样做有技巧吗?还是我走错了方向?
答案 0 :(得分:0)
您在做什么并不常见
您有x,y,r,g,b,m [0],m [1],m [2],m [3],m [4],m [5],m [6 ],m [7],m [8],m [9],m [10],m [11],m [12],m [13],m [14],m [15]每个顶点大步前进,因为您要尝试将所有数据放在同一个缓冲区中,所以
21 * Float32Array.BYTES_PER_ELEMENT
然后您需要为mat4设置4个属性,每个属性的大小为4(4个属性,每个大小4 =矩阵的16个值)
// Set Pointers
const stride = 21 * Float32Array.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, stride, 2 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(a_xformMatrix + 0, 4, gl.FLOAT, false, stride, 5 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(a_xformMatrix + 1, 4, gl.FLOAT, false, stride, 9 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(a_xformMatrix + 2, 4, gl.FLOAT, false, stride, 13 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(a_xformMatrix + 3, 4, gl.FLOAT, false, stride, 17 * Float32Array.BYTES_PER_ELEMENT);
此外,此代码还没有将矩阵数据放入Float32Array中。您可以编写一些代码来合并数据,或者如果您想手工完成
var vertices = new Float32Array(
[ // x, y r, g, b rotate matrix
0.0, 0.5, 1.0, 0.0, 0.0,
xformMatrix[0][0], xformMatrix[0][1], xformMatrix[0][2], xformMatrix[0][3],
xformMatrix[0][4], xformMatrix[0][5], xformMatrix[0][6], xformMatrix[0][7],
xformMatrix[0][8], xformMatrix[0][9], xformMatrix[0][10], xformMatrix[0][11],
xformMatrix[0][12], xformMatrix[0][13], xformMatrix[0][14], xformMatrix[0][15],
... repeat for the next vertex ..
]);
请注意,如果您的代码可以工作,我不会费心检查是否进行了所有这些更改。最明显的问题就是基于您所说的那样。
您可能会发现,如果采用这种方式,尝试旋转三角形时您将要更新大量数据,因此您可能希望找到其他方法。
签出these tutorials。第一篇文章绘制了一堆不同颜色的矩形。它对每种颜色使用一次绘制调用,这是最常见的方法。然后在下面的文章中建立使用矩阵的方法。
您还可以仅传递每个三角形的旋转并在着色器中计算旋转。这样,每个顶点的每个三角形只有一个旋转值,而不是每个顶点的每个矩阵都有一个旋转值。您必须为每个三角形更新3个旋转以对其进行动画处理。
您还可以间接地通过纹理,因此,每个顶点每个三角形都有一个三角形ID,而不是每个顶点每个三角形都有一个旋转。因此,前3个顶点的ID = 0,后3个ID = 1,依此类推。将其作为属性传递,然后可以像rotation = ID * constant
中那样使用它生成旋转,或者可以使用该ID查找如rotation = texture2D(textureWithRotationData, vec2((id + .5) / textureWidth, 0.5).r
中的纹理旋转。这种方法的优点是您只需要更新每个三角形1圈。纹理中的一个。