如何设置关键帧动画比例并从 webGL 立方体的锚点旋转?
How to keyframe animate a scale and rotate from an anchor point of a webGL cube?
我在 WebGL 中创建了一个立方体。我有一个动画,但正在努力将它组合在一起。
完整的代码大约是 150 lns 的代码,所以这是一个工作示例:
Working Plunkr Code
这是动画的视频线框,我正在努力实现:
https://youtu.be/sZeBm8EM3mw
1 - 动画将锚点设置到立方体的左下角。
2 - 动画从锚点开始缩放立方体。
3 - 动画将立方体从锚点旋转大约一半比例。
着色器:
(顶点)
attribute vec4 coords;
attribute float pointSize;
uniform mat4 transformMatrix;
attribute vec4 colors;
varying vec4 varyingColors;
uniform mat4 perspectiveMatrix;
void main(void) {
gl_Position = perspectiveMatrix * transformMatrix * coords;
gl_PointSize = pointSize;
varyingColors = colors;
}
(片段)
precision mediump float;
uniform vec4 color;
varying vec4 varyingColors;
void main(void) {
gl_FragColor = varyingColors;
}
我正在使用 gl-matrix 进行矩阵变换
转换将在绘图 fn 中进行并使用 gl 矩阵 mat4。
function draw() {
var transformMatrix = gl.getUniformLocation(shaderProgram, "transformMatrix");
gl.uniformMatrix4fv(transformMatrix, false, matrix);
// mat4.rotateY(matrix, matrix, 0.01); // This is example of rotations
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_BYTE, 0);
requestAnimationFrame(draw);
}
您必须在转换中添加所谓的 "Pivot"。通常和简单的转换定义如下:
transform = scale * rotate * translate;
其中:
scale = | rotate = | translate =
Sx 0 0 0 | Xx Xy Xz 0 | 1 0 0 0
0 Sy 0 0 | Yx Yy Yz 0 | 0 1 0 0
0 0 Sz 0 | Zx Zy Zz 0 | 0 0 1 0
0 0 0 1 | 0 0 0 1 | Tx Ty Tz 1
要围绕枢轴点(锚点)执行 rotation/scale,您必须添加描述枢轴位置(相对于对象中心)的枢轴矩阵:
pivot =
1 0 0 0
0 1 0 0
0 0 1 0
Px Py Pz 1
你的转换公式如下:
transform = inverse(pivot) * scale * rotate * pivot * translate;
问题是,虽然 scale * rotate * translate
很容易优化(简化以避免真正的矩阵乘法),但对于 pivot 这变得更难以优化。
注意:您还可以从 this documentation 获得灵感,这是 Maya API 变换 Class 文档,它提供了一个 'overkill' 变换公式.我过去用它来了解转换的工作原理。
我在 WebGL 中创建了一个立方体。我有一个动画,但正在努力将它组合在一起。
完整的代码大约是 150 lns 的代码,所以这是一个工作示例: Working Plunkr Code
这是动画的视频线框,我正在努力实现: https://youtu.be/sZeBm8EM3mw
1 - 动画将锚点设置到立方体的左下角。
2 - 动画从锚点开始缩放立方体。
3 - 动画将立方体从锚点旋转大约一半比例。
着色器: (顶点)
attribute vec4 coords;
attribute float pointSize;
uniform mat4 transformMatrix;
attribute vec4 colors;
varying vec4 varyingColors;
uniform mat4 perspectiveMatrix;
void main(void) {
gl_Position = perspectiveMatrix * transformMatrix * coords;
gl_PointSize = pointSize;
varyingColors = colors;
}
(片段)
precision mediump float;
uniform vec4 color;
varying vec4 varyingColors;
void main(void) {
gl_FragColor = varyingColors;
}
我正在使用 gl-matrix 进行矩阵变换
转换将在绘图 fn 中进行并使用 gl 矩阵 mat4。
function draw() {
var transformMatrix = gl.getUniformLocation(shaderProgram, "transformMatrix");
gl.uniformMatrix4fv(transformMatrix, false, matrix);
// mat4.rotateY(matrix, matrix, 0.01); // This is example of rotations
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_BYTE, 0);
requestAnimationFrame(draw);
}
您必须在转换中添加所谓的 "Pivot"。通常和简单的转换定义如下:
transform = scale * rotate * translate;
其中:
scale = | rotate = | translate =
Sx 0 0 0 | Xx Xy Xz 0 | 1 0 0 0
0 Sy 0 0 | Yx Yy Yz 0 | 0 1 0 0
0 0 Sz 0 | Zx Zy Zz 0 | 0 0 1 0
0 0 0 1 | 0 0 0 1 | Tx Ty Tz 1
要围绕枢轴点(锚点)执行 rotation/scale,您必须添加描述枢轴位置(相对于对象中心)的枢轴矩阵:
pivot =
1 0 0 0
0 1 0 0
0 0 1 0
Px Py Pz 1
你的转换公式如下:
transform = inverse(pivot) * scale * rotate * pivot * translate;
问题是,虽然 scale * rotate * translate
很容易优化(简化以避免真正的矩阵乘法),但对于 pivot 这变得更难以优化。
注意:您还可以从 this documentation 获得灵感,这是 Maya API 变换 Class 文档,它提供了一个 'overkill' 变换公式.我过去用它来了解转换的工作原理。