繁体   English   中英

绕 X 以外的轴旋转使 3D object 平坦

[英]Rotation around axis other than X makes 3D object flat

在我的程序中,我从 GLTF 文件加载一个立方体,并使用我自己实现的数学对象(如向量、矩阵和四元数)来显示它。

这就是我尝试旋转立方体时程序绘制的内容:

X旋转:

在此处输入图像描述

和 Y 旋转:

在此处输入图像描述

如您所见,如果我的立方体是平的,Y 旋转看起来就像。

我试图找到罪魁祸首,但现在它让我望而却步。 但我 100% 确定:

  • 这不是 GLTF 加载器故障,因为我的测试显示立方体的数据已正确加载
  • 这不是我的数学模块错误,因为我的测试再次告诉我计算正确
  • 它仅在我尝试绕 Y 轴和 Z 轴旋转时发生。 X轴旋转不知何故没有这个问题

我唯一不确定的是着色器。 但我的着色器代码是最简单的:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

uniform mat4 projection;
uniform mat4 view;

out vec3 fragNormal;
out float distance;

void main()
{
    gl_Position = projection * view * vec4(position, 1.0);
    vec4 tmp = view * vec4(position, 1.0);
    distance = tmp.z + 10.0;
    fragNormal = normal;
}
#version 330 core
in vec3 fragNormal;
in float distance;

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f) * distance;
}

我真的不知道我还能去哪里找。 另外,我想给你我的程序 rest 的代码,但在这一点上显然不可能把它放在这篇文章中,因为我的程序有很多行代码。

那么,这个错误是如何发生的呢?

编辑:

我的投影矩阵是标准视角,fov=45°,near=0.1,far=100.0:

|1.29996 0 0 0 |
|0 2.41421 0 0 |
|0 0 -1.002 -0.2002 |
|0 0 -1 0 |

视图矩阵发生变化:它是一个平移矩阵 (x=0,y=0,z=-10) 乘以(从右边开始)一个旋转矩阵(在下面的列表中围绕 Y 轴一定程度)

| 0.5 0 0 0 |
| 0 1 0 0 |
| -0.866026 0 0.5 -10 |
| 0 0 0 1 |

旋转取自四元数,但也可以直接从旋转矩阵计算。 无论我如何计算旋转矩阵,都会发生错误。

我发现错误在哪里:在矩阵 class 的乘法方法中。这段代码不知何故:

mat4 operator* (const mat4& other) const {
    T _c11 = c11 * other.c11 + c12 * other.c21 + c13 * other.c31 + c14 * other.c41;
    T _c12 = c11 * other.c12 + c12 * other.c22 + c13 * other.c32 + c14 * other.c42;
    T _c13 = c11 * other.c13 + c12 * other.c23 + c13 * other.c33 + c14 * other.c43;
    T _c14 = c11 * other.c14 + c12 * other.c24 + c13 * other.c34 + c14 * other.c44;
    
    T _c21 = c21 * other.c11 + c22 * other.c21 + c23 * other.c31 + c24 * other.c41;
    T _c22 = c21 * other.c12 + c22 * other.c22 + c23 * other.c32 + c24 * other.c42;
    T _c23 = c21 * other.c13 + c22 * other.c23 + c23 * other.c33 + c24 * other.c43;
    T _c24 = c21 * other.c14 + c22 * other.c24 + c23 * other.c34 + c24 * other.c44;
    
    T _c31 = c31 * other.c11 + c32 * other.c21 + c33 * other.c31 + c34 * other.c41;
    T _c32 = c31 * other.c12 + c32 * other.c22 + c33 * other.c32 + c34 * other.c42;
    T _c33 = c31 * other.c13 + c32 * other.c23 + c33 * other.c33 + c34 * other.c43;
    T _c34 = c31 * other.c14 + c32 * other.c24 + c33 * other.c34 + c34 * other.c44;
    
    T _c41 = c41 * other.c11 + c42 * other.c21 + c43 * other.c31 + c44 * other.c41;
    T _c42 = c41 * other.c12 + c42 * other.c22 + c43 * other.c32 + c44 * other.c42;
    T _c43 = c41 * other.c13 + c42 * other.c23 + c43 * other.c33 + c44 * other.c43;
    T _c44 = c41 * other.c14 + c42 * other.c24 + c43 * other.c34 + c44 * other.c44;
    
    return mat4{_c11, c12, c13, _c14, 
                _c21, _c22, _c23, _c24, 
                _c31, _c32, _c33, _c34,
                _c41, _c42, _c43, _c44};
}

不像这段代码那样工作:

mat4 operator* (const mat4& other) const {
    mat4<T> result;
    result.c11 = c11 * other.c11 + c12 * other.c21 + c13 * other.c31 + c14 * other.c41;
    result.c12 = c11 * other.c12 + c12 * other.c22 + c13 * other.c32 + c14 * other.c42;
    result.c13 = c11 * other.c13 + c12 * other.c23 + c13 * other.c33 + c14 * other.c43;
    result.c14 = c11 * other.c14 + c12 * other.c24 + c13 * other.c34 + c14 * other.c44;
    
    result.c21 = c21 * other.c11 + c22 * other.c21 + c23 * other.c31 + c24 * other.c41;
    result.c22 = c21 * other.c12 + c22 * other.c22 + c23 * other.c32 + c24 * other.c42;
    result.c23 = c21 * other.c13 + c22 * other.c23 + c23 * other.c33 + c24 * other.c43;
    result.c24 = c21 * other.c14 + c22 * other.c24 + c23 * other.c34 + c24 * other.c44;
    
    result.c31 = c31 * other.c11 + c32 * other.c21 + c33 * other.c31 + c34 * other.c41;
    result.c32 = c31 * other.c12 + c32 * other.c22 + c33 * other.c32 + c34 * other.c42;
    result.c33 = c31 * other.c13 + c32 * other.c23 + c33 * other.c33 + c34 * other.c43;
    result.c34 = c31 * other.c14 + c32 * other.c24 + c33 * other.c34 + c34 * other.c44;
    
    result.c41 = c41 * other.c11 + c42 * other.c21 + c43 * other.c31 + c44 * other.c41;
    result.c42 = c41 * other.c12 + c42 * other.c22 + c43 * other.c32 + c44 * other.c42;
    result.c43 = c41 * other.c13 + c42 * other.c23 + c43 * other.c33 + c44 * other.c43;
    result.c44 = c41 * other.c14 + c42 * other.c24 + c43 * other.c34 + c44 * other.c44;
    
    return result;
}

可能我遇到了一些编译器实现细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM