为什么我的旋转立方体看起来不像旋转立方体? 我需要移动相机吗? 我不知道出了什么问题。 我在
glium
中使用rust
。
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 shading(来自
glium
教程)进行照明。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.代码太多了,但我不知道我还能提供什么。
您的旋转矩阵是围绕 X 轴的旋转,并且您没有应用透视投影矩阵,因此您得到隐含的默认正交投影。你的照片或多或少是你在那种情况下得到的典型例子,尽管可能还有更多的错误,可能在顶点数据中(我注意到可见的对角线)。
顶点在 YZ 平面中绕 X 轴圆周移动,您无法直接看到 Z,所以您只能看到它们在 Y 中上下移动。
为了获得看起来像旋转立方体的图片,您需要设置透视投影,并且可能需要设置正在观察立方体的相机位置/旋转(视图矩阵)。
或者您可以尝试将矩阵更改为绕 Z 轴旋转的矩阵:
let m = [
[t.cos(), -t.sin(), 0.0, 0.0],
[t.sin(), t.cos(), 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0f32]
];
这将是一个明显的轮换。
但总的来说,我强烈建议在你的程序中使用透视投影。这将揭示 Z 轴(目前不可见)的运动,并使图像对人类视觉更直观。添加更多对象和更复杂的对象,创建更完整的“场景”也很有用——然后如果您有代码错误,您可以看到它们如何影响 all 正在显示的几何体,而不是只看到一个非常你现在拥有的一堆抽象矩形。