当纵横比不是 1:1 时,如何在旋转时更正矩阵的缩放比例

How do I correct the matrix's scaling when rotating when aspect ratio is not 1:1

我有一个带有纹理的旋转矩阵。当正交场景的纵横比为1:1时,像600px和600px,完美旋转。但是,如果我将高度增加到 1200,我会遇到一些问题。它看起来好像矩阵的水平轴被缩放,就好像它没有旋转一样。

假设我有一个 600x1200 的场景,我的矩阵应该是 30x30。如果矩阵没有旋转,它的 x 比例应该是 0.05*600,也就是 30px。如果我将矩阵旋转 90 度,它的 x 比例应该是 0.025*1200,也就是 30px。但是我没有什么可以弥补这一点,矩阵比例总是一样的,就好像它没有被旋转一样。

我该如何补偿?

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

void main()
{   

fragColor = vertColor;

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


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



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

}

当角度接近 90 度和 270 度时,我尝试使用 Math.sin 减小 x 比例,但它没有按预期工作。

通常,纵横比被编码到投影矩阵中。投影矩阵是应用于顶点坐标的最后一个变换。

如果你想在顶点着色器中应用纵横比,它是这样工作的:

方面矩阵:

float aspect = width / height;

mat4 aspect_mat = mat4(
    vec4(1.0/aspect, 0.0, 0.0, 0.0), 
    vec4(0.0,        1.0, 0.0, 0.0), 
    vec4(0.0,        0.0, 1.0, 0.0), 
    vec4(0.0,        0.0, 0.0, 1.0)); 

mat4 model_mat = 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));

mat4 worldPosTrans = aspect_mat * model_mat;

这导致:

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