首页 > 解决方案 > 如何在webgl的模型视图矩阵中设置旋转轴

问题描述

我从 webgl 基础研究这个旋转代码,它围绕 0 0 原点旋转对象。https://jsfiddle.net/eguneys/5s7n82pt/6/。我自己编写了完全相同的代码,当我旋转时,它围绕中间点(宽度/ 2,高度/ 2)旋转并且它不能正确旋转,它会倾斜并且不起作用。

所以我的问题是为什么会发生这种情况,以及如何围绕中间点旋转这个示例代码。

in vec2 a_position;

// Used to pass in the resolution of the canvas
uniform vec2 u_resolution;

// A matrix to transform the positions by
uniform mat3 u_matrix;

// all shaders have a main function
void main() {
  // Multiply the position by the matrix.
  vec2 position = (u_matrix * vec3(a_position, 1)).xy;

  // convert the position from pixels to 0.0 to 1.0
  vec2 zeroToOne = position / u_resolution;

  // convert from 0->1 to 0->2
  vec2 zeroToTwo = zeroToOne * 2.0;

  // convert from 0->2 to -1->+1 (clipspace)
  vec2 clipSpace = zeroToTwo - 1.0;

  gl_Position = vec4(clipSpace, 0, 1);
}

标签: javascriptwebgl

解决方案


The article you got that shader from this clear this article

您显然没有读完这篇文章,因为该着色器来自文章的顶部,而文章的全部要点是该着色器可以简化为

#version 300 es

in vec2 a_position;

uniform mat3 u_matrix;

void main() {
  gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
}

它指出了为什么这样做更好,原因之一是您可以在不更改着色器的情况下移动枢轴点。它给出了一个示例,其中更改了示例模型的枢轴

它以这样的代码开始,其中模型围绕其本地原点旋转,该原点是模型的左上角

var translationMatrix = m3.translation(translation[0], translation[1]);
var rotationMatrix = m3.rotation(rotationInRadians);
var scaleMatrix = m3.scaling(scale[0], scale[1]);

// Multiply the matrices.
var matrix = m3.multiply(translationMatrix, rotationMatrix);
matrix = m3.multiply(matrix, scaleMatrix);

并将枢轴移动到模型的中心,模型宽 100 单位,高 150 单位,如下所示。

var translationMatrix = m3.translation(translation[0], translation[1]);
var rotationMatrix = m3.rotation(rotationInRadians);
var scaleMatrix = m3.scaling(scale[0], scale[1]);

// make a matrix that will move the origin of the 'F' to its center.
var moveOriginMatrix = m3.translation(-50, -75);
...

// Multiply the matrices.
var matrix = m3.multiply(translationMatrix, rotationMatrix);
matrix = m3.multiply(matrix, scaleMatrix);
matrix = m3.multiply(matrix, moveOriginMatrix);

再往下,它简化了这些功能,所以你可以做到这一点

// Multiply the matrices.
var matrix = m3.projection(gl.canvas.clientWidth, gl.canvas.clientHeight);
matrix = m3.translate(matrix, x, y);
matrix = m3.rotate(matrix, angle);
matrix = m3.scale(matrix, sx, sy);
matrix = m3.translate(matrix, centerOffsetX, centerOffsetY);

该系列还跟进了两个矩阵堆栈,基本上再现了画布 2d 矩阵系统以及大多数 3D 引擎使用的场景图。SVG 等结构化绘图系统和 Illustrator 等应用程序也使用场景图。矩阵堆栈和场景图都可以轻松更改旋转轴心点。


推荐阅读