为什么我的旋转立方体看起来不像旋转立方体?我需要移动相机吗?我不知道出了什么问题。我在rust
中使用glium
。
24个顶点
const P: f32 = 0.5;
let vertex_buffer = glium::VertexBuffer::new(&display, &vec![
// front 0-3
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (P, P, 0.0) },
Vertex { position: (P, -P, 0.0) },
Vertex { position: (-P, P, 0.0) },
// back 4-7
Vertex { position: (-P, -P, 1.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (-P, P, 1.0) },
// up 8-11
Vertex { position: (-P, P, 0.0) },
Vertex { position: (P, P, 0.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (-P, P, 1.0) },
// down 12-15
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (P, -P, 0.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (-P, -P, 1.0) },
// right 16-19
Vertex { position: (P, -P, 0.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (P, P, 0.0) },
// left 20-23
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (-P, -P, 1.0) },
Vertex { position: (-P, P, 1.0) },
Vertex { position: (-P, P, 0.0) },
]
).unwrap();
生成立方体的6个面(每个面4个顶点,每个面2个三角形)的指数:
let indices = glium::IndexBuffer::new(&display, glium::index::PrimitiveType::TrianglesList,
&[
// front
0, 2, 1,
0, 3, 1,
// back
4, 6, 5,
4, 7, 5,
// up
8, 9, 10,
8, 11, 10,
// down
12, 13, 14,
12, 15, 14,
// right
16, 17, 18,
16, 19, 18,
// left
20, 21, 22,
20, 23, 22u16,
]
).unwrap();
我正在使用 * Gouraud着色 *(来自glium
教程)进行照明。
我在堆栈溢出中找到了cube的normals
。Normals
:
let normals = glium::VertexBuffer::new(&display, &vec![
// front
Normal { normal: (1.0, 0.0, 0.0) },
// back
Normal { normal: (0.0, -1.0, 0.0) },
// up
Normal { normal: (1.0, 0.0, -1.0) },
// down
Normal { normal: (0.0, 0.0, 1.0) },
// right
Normal { normal: (1.0, 0.0, 0.0) },
// left
Normal { normal: (-1.0, 0.0, 0.0) },
]
).unwrap();
顶点着色器(glsl
):
#version 150
in vec3 position;
in vec3 normal;
out vec3 v_normal;
uniform mat4 m;
void main() {
v_normal = transpose(inverse(mat3(m))) * normal;
gl_Position = m * vec4(position, 1.0);
}
片段着色器(glsl
):
#version 150
in vec3 v_normal;
out vec4 color;
uniform vec3 u_light;
void main() {
float brightness = dot(normalize(v_normal), normalize(u_light));
vec3 dark_color = vec3(0.6, 0.0, 0.0);
vec3 regular_color = vec3(1.0, 0.0, 0.0);
color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}
通过4x4矩阵进行旋转:
let mut t: f32 = 0.0;
let mut s: f32 = 0.002;
// ... loop.run
t += s;
if t > 180.0 || t < -180.0 {
s = -s;
}
let m = [
[1.0, 0.0, 0.0, 0.0],
[0.0, t.cos(), -t.sin(), 0.0],
[0.0, t.sin(), t.cos(), 0.0],
[0.0, 0.0, 0.0, 1.0f32]
];
let light = [-1.0, -0.4, 0.9f32];
// params
target.draw((&vertex_buffer, &normals), &indices, &program, &uniform! { m: m, u_light: light }, ¶ms).unwrap();
target.finish().unwrap();
有什么想法是错的吗?我很抱歉这么长的 * Q. * 有这么多的代码,但我不知道还有什么比这我可以提供。
下面是我的"旋转立方体"的一些图片:第一节第一节第一节第一节第二节第一节第三节第一节
1条答案
按热度按时间mefy6pfw1#
你的旋转矩阵是绕X轴的旋转,并且你没有应用透视投影矩阵,所以你得到了默认的正交投影。你的图片或多或少是你在这种情况下得到的典型例子,尽管可能有更多的错误,也许在顶点数据中(我注意到了可见的对角线)。
顶点在YZ平面上绕X轴做圆周运动,你不能直接看到Z轴,所以只能看到它们在Y轴上上下运动。
为了得到一张看起来像旋转立方体的图片,你需要设置一个透视投影,可能还要设置一个正看着立方体的相机位置/旋转(视图矩阵)。
或者,您可以尝试将矩阵更改为绕Z轴旋转的矩阵:
这将是一个明显的轮换。
但总的来说,我强烈建议在程序中使用透视投影,这样可以显示Z轴上的运动(目前不可见),使图像对人类视觉更直观。添加更多对象和更复杂的对象,制作更完整的“场景”也很有用-然后如果你有代码错误,你可以看到它们是如何影响正在显示的“所有”几何图形的,而不是像你现在看到的那样,只看到一堆非常抽象的矩形。