0

I want to rotate each texture individually in my rendercall. I read this tutorial, and it works as i want it to except that the rotation is applied to all objects(due to the rotation value being uniform).

So i rewrote it to use a buffer but i cant get it to work properly.

Heres my shader:

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;
} 

and typescript code

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);

I get no errors from webgl or from the browser but end up with a blank canvas. Any ideas?

  • Normally you'd set attributes, uniforms, draw one object, then set attributes (unless they're the same), set uniforms, draw a 2nd object. Etc.. [See this answer](http://stackoverflow.com/questions/39758504/webgl-drawing-multiple-shapes-of-different-colour) or [this article](https://webglfundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html) – gman Mar 26 '17 at 15:59
  • Note: I'd suggest you keep reading. That article you linked to is step 2 of about 8 on the way to doing things in a much more flexible (and common) way. – gman Mar 26 '17 at 16:07
  • Wouldent setting the uniform for each object result in terrible performace? – Emil Sunesson Mar 26 '17 at 16:10
  • [No](http://stackoverflow.com/questions/26564104/use-single-vertex-buffer-or-many/26568792#26568792) – LJᛃ Mar 26 '17 at 23:22
  • It's normal to have many draw calls. [Doom 2016](http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/) (1331 draw calls), [GTAV](http://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study/) (thousands of draw calls), [Deus EX](http://www.adriancourreges.com/blog/2015/03/10/deus-ex-human-revolution-graphics-study/) (900 draw calls). Also don't prematurely optimized. There's no reason to put things in one buffer and use offsets or anything like that until you're making something like one of the games above. – gman Mar 27 '17 at 00:05
  • One other thing. You might be interested in [this article](https://webglfundamentals.org/webgl/lessons/webgl-2d-matrix-stack.html) and the one before it – gman Mar 27 '17 at 02:49
  • ok, thanks for the info ill check it out! – Emil Sunesson Mar 27 '17 at 17:13

1 Answers1

1

After much digging around in matrix math and how to use it in webgl. I came up with a solution that worked well for my specific problem. Creating a rendercall for each object(squares 6 vertices) turned out to effect the performance quite drastically.

As i only needed to rotate a few objects each rendering cycle i rotated the vertecies directly in javascript.

Something like this:

    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]
    ];

Where Matrix3 is more or less a copy from Webglfundamentals helper class for 3x3 matrix math, from 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];
}

Also check out this answer for a simple example of how to do the rotation in the shader.

Other helpful sources

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
Community
  • 1
  • 1