文档中说
透视投影后的 w 表示的是透视投影前的 z 值。
所以我试了试,使用透视投影前的.z() 值时:
Vector3f Zt = {t.world_pos[0].z(), t.world_pos[1].z(), t.world_pos[2].z()};
得到的图片是这样的:
图中用红线圈起来的地方可以看到黑点,尤其是奶牛腰部的地方失真还挺严重的。
使用透视投影后的.w() 值时:
Vector3f Zt = {t.viewport_pos[0].w(), t.viewport_pos[1].w(), t.viewport_pos[2].w()};
渲染出来的奶牛就正常了:
这样看来透视投影后的.w() 跟透视投影前的.z() 应该有点区别啊?
(ps:
写着写着这个帖子自己想明白了。透视投影后的.w() 跟透视投影前的.z() 确有相反数的关系,但是我在顶点渲染器里对 world_pos 和 viewport_pos 进行实际计算的方法不一样,所以它俩计算出来的值应该有细微的差别,这种细微的差别导致了第一张图的黑点。
不过不太确定黑点的具体成因,按理说是片元/像素的 color 值为 0 了,但是根据着色器的计算,片元不太可能真黑,应该是深度检测出了问题吧,导致后面的黑色块被判定成在前面了。
另外,
// set Uniforms for vertex shader
Uniforms::MVP = cam.projection() * cam.view() * object->model();
Uniforms::inv_trans_M = object->model().inverse().transpose();
Uniforms::width = static_cast<int>(this->width);
Uniforms::height = static_cast<int>(this->height);
// To do: 同步
Uniforms::material = object->mesh.material;
Uniforms::lights = scene.lights;
Uniforms::camera = scene.camera;
这部分代码我未做任何改动仍然能渲染出 2.2 所要求的结果。此处的 To do 是否是不必要的?