【问题标题】:Rotating textures individually using webgl使用 webgl 单独旋转纹理
【发布时间】:2017-03-30 04:54:26
【问题描述】:

我想在我的渲染调用中单独旋转每个纹理。我阅读了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 或浏览器的错误,但最终得到一个空白画布。有什么想法吗?

【问题讨论】:

  • 通常你会设置属性,制服,绘制一个对象,然后设置属性(除非它们相同),设置制服,绘制第二个对象。等等。See this answerthis article
  • 注意:我建议您继续阅读。您链接到的那篇文章是关于以更灵活(和常见)的方式做事的大约 8 步中的第 2 步。
  • 为每个对象设置制服会导致糟糕的性能吗?
  • No
  • 有很多draw call是正常的。 Doom 2016(1331 个绘图调用)、GTAV(数千个绘图调用)、Deus EX(900 个绘图调用)。也不要过早优化。没有理由将东西放在一个缓冲区中并使用偏移量或类似的东西,直到您制作类似于上述游戏之一的东西。

标签: rotation webgl


【解决方案1】:

经过大量研究矩阵数学以及如何在 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 辅助类的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    相关资源
    最近更新 更多