使用 webgl 单独旋转纹理

Rotating textures individually using webgl

我想在渲染调用中单独旋转每个纹理。我阅读了 this 教程,它按照我想要的方式工作,除了旋转应用于所有对象(由于旋转值是统一的)。

所以我重写了它以使用缓冲区,但我无法让它正常工作。

这是我的着色器:

attribute vec2 a_position;
attribute vec2 a_texture_coord;
attribute vec2 a_rotation;
attribute vec4 a_color;

uniform vec2 u_resolution;

varying highp vec2 v_texture_coord;
varying vec4 v_color;

void main() {
  v_color = a_color;
  vec2 rotatedPosition = vec2(
     a_position.x * a_rotation.y + a_position.y * a_rotation.x,
     a_position.y * a_rotation.y - a_position.x * a_rotation.x);
  vec2 zeroToOne = rotatedPosition / u_resolution;
  vec2 zeroToTwo = zeroToOne * 2.0;
  vec2 clipSpace = zeroToTwo - 1.0;

  gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
  v_texture_coord = a_texture_coord;
} 

和打字稿代码

this.gl.enableVertexAttribArray(this.rotationAttributeLocation);

this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.rotationBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(renderCall.rotation), this.gl.STATIC_DRAW);

this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.rotationBuffer);
this.gl.vertexAttribPointer(this.rotationAttributeLocation, 2, this.gl.FLOAT, false, 0, 0);

我没有从 webgl 或浏览器中收到任何错误,但最终得到一个空白 canvas。有什么想法吗?

在深入研究矩阵数学以及如何在 webgl 中使用它之后。 我想出了一个解决方案,可以很好地解决我的特定问题。 为每个对象(正方形 6 个顶点)创建一个渲染调用结果对性能产生了相当大的影响。

因为我只需要在每个渲染周期旋转几个对象,所以我直接在 javascript 中旋转顶点。

像这样:

    let x1 = x + width;
    let x2 = x;
    let y1 = y;
    let y2 = y + height;

    let rotatePointX = x2;
    let rotatePointY = y1;

    let moveToRotationPointMatrix = Matrix3.createTranslationMatrix(-rotatePointX, -rotatePointY);
    let rotationMatrix = Matrix3.createRotationMatrix(angle);
    let moveBackMatrix = Matrix3.createTranslationMatrix(rotatePointX, rotatePointY);

    let matrix = Matrix3.multiply(moveToRotationPointMatrix, rotationMatrix);
    matrix = Matrix3.multiply(matrix, moveBackMatrix);

    let x1y1 = Matrix3.positionConvertion(x1, y1, matrix);
    let x2y2 = Matrix3.positionConvertion(x2, y2, matrix);
    let x2y1 = Matrix3.positionConvertion(x2, y1, matrix);
    let x1y2 = Matrix3.positionConvertion(x1, y2, matrix);

    let newVertecies = [
        x1y1[0], x1y1[1],
        x2y2[0], x2y2[1],
        x2y1[0], x2y1[1],
        x1y1[0], x1y1[1],
        x2y2[0], x2y2[1],
        x1y2[0], x1y2[1]
    ];

其中 Matrix3 或多或少是 Webglfundamentals helper class 的副本,用于 3x3 矩阵数学,来自 here

public static positionConvertion(x: number, y: number, matrix: number[]) {
    x = x * matrix[0] + y * matrix[3] + 1 * matrix[6];
    y = x * matrix[1] + y * matrix[4] + 1 * matrix[7];

    return [x, y];
}

另请查看 this 答案,了解如何在着色器中进行旋转的简单示例。

其他有用的资源

webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html
webglfundamentals.org/webgl/lessons/webgl-2d-matrix-stack.html
webglfundamentals.org/webgl/lessons/webgl-2d-rotation.html