旋转顶点具有不同的高度/宽度

时间:2018-04-15 15:16:49

标签: matrix rotation webgl coordinate-transformation

我正在尝试在webgl中旋转图像。如果纹理与高度具有相同的宽度,则没有问题,但如果宽度为例如256px且高度仅为32px,则图像会偏斜。

似乎只有纹理旋转而不是顶点。然而,通常当只有纹理旋转时,它的角落会在顶点移动时被剪裁。这不会发生在这里,所以我有点困惑。

enter image description here

这是我的顶点着色器代码:

precision lowp float;

attribute vec3 vertPosition;
attribute vec3 vertColor;
attribute vec2 aTextureCoord;
varying vec3 fragColor;
varying lowp vec2 vTextureCoord;

varying lowp vec2 vTextureCoordBg;
uniform vec2 uvOffsetBg;
uniform vec2 uvScaleBg;

uniform mat4 uPMatrix;

uniform vec2 uvOffset;
uniform vec2 uvScale;

uniform vec3 translation;
uniform vec3 scale;
uniform float rotateZ;
uniform vec2 vertPosFixAfterRotate;

void main()
{       
    fragColor = vertColor;

    vTextureCoord = (vec4(aTextureCoord.x, aTextureCoord.y, 0, 1)).xy * uvScale + uvOffset;
    vTextureCoordBg = (vec4(aTextureCoord, 0, 1)).xy * uvScaleBg + uvOffsetBg;

    mat4 worldPosTrans = mat4(
        vec4(scale.x*cos(rotateZ),  scale.y*-sin(rotateZ),  0,              0), 
        vec4(scale.x*sin(rotateZ),  scale.y*cos(rotateZ),   0,              0), 
        vec4(0,                     0,                      scale.z,        0), 
        vec4(translation.x,         translation.y,          translation.z,  1));

    gl_Position = (uPMatrix * worldPosTrans) * vec4(vertPosition.x + vertPosFixAfterRotate.x, vertPosition.y + vertPosFixAfterRotate.y, vertPosition.z, 1.0);
}

旋转通过rotateZ制服从javascript发送到着色器。

1 个答案:

答案 0 :(得分:1)

你必须在轮换前进行缩放:

比例矩阵:

mat4 sm = mat4(
    vec4(scale.x, 0.0,     0.0,     0.0), 
    vec4(0.0,     scale.y, 0.0,     0.0), 
    vec4(0.0,     0.0,     scale.z, 0.0), 
    vec4(0.0,     0.0,     0.0,     1.0));

旋转矩阵:

mat4 rm = mat4(
    vec4(cos(rotateZ), -sin(rotateZ),  0.0, 0.0), 
    vec4(sin(rotateZ), cos(rotateZ),   0.0, 0.0), 
    vec4(0.0,          0.0,            1.0, 0.0), 
    vec4(0.0,          0.0,            0.0, 1.0));

翻译矩阵:

mat4 tm = mat4(
    vec4(1.0,           0.0,           0.0,           0.0), 
    vec4(0.0,           1.0,           0.0,           0.0), 
    vec4(0.0,           0.0,           0.0,           0.0), 
    vec4(translation.x, translation.y, translation.z, 1.0));

模型转换:

mat4 worldPosTrans = tm * rm * sm;

与您问题中的代码段相比,查看结果并关注scale.xscale.y

mat4 worldPosTrans = mat4(
    vec4(scale.x * cos(rotateZ), scale.x * -sin(rotateZ),  0.0,            0.0), 
    vec4(scale.y * sin(rotateZ), scale.y * cos(rotateZ),   0.0,            0.0), 
    vec4(0.0,                    0.0,                      scale.z,        0.0), 
    vec4(translation.x,          translation.y,            translation.z,  1.0));