[CG] 沿 y 轴观察时无法正常渲染物体的原因
之前做 CG 课 lab2 的时候遇到了如标题所示的问题,当时并不知道原因。不久前又一次遇到该问题,这次我决定把它搞明白。
我使用 RenderDoc 对出错的部分进行了 profiling,发现传递给 GPU 的 uniform 变量 viewMatrix 里面有大量的 NaN 项,考虑到我的观察矩阵使用 glm::lookAt
函数产生,所以猜想问题与它有关。
当然,函数本身出错的概率,特别是对于 GLM 这种历史悠久的数学库而言,是极低的,但也无法排除这一可能,因此放在最后考虑吧。
目前唯一的线索只有 观察方向,我想,得先把观察方向与 lookAt
函数之间的关系搞明白,于是找到了 lookAt
的源码(下面贴的是 lookAtRH
,适用于 OpenGL 的右手坐标系,相应的还有 lookAtLH
,两个函数区别很小):
template <typename T, qualifier Q> GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const &eye, vec<3, T, Q> const ¢er, vec<3, T, Q> const &up) { vec<3, T, Q> const f(normalize(center - eye)); vec<3, T, Q> const s(normalize(cross(f, up))); vec<3, T, Q> const u(cross(s, f)); mat<4, 4, T, Q> Result(1); Result[0][0] = s.x; Result[1][0] = s.y; Result[2][0] = s.z; Result[0][1] = u.x; Result[1][1] = u.y; Result[2][1] = u.z; Result[0][2] = -f.x; Result[1][2] = -f.y; Result[2][2] = -f.z; Result[3][0] = -dot(s, eye); Result[3][1] = -dot(u, eye); Result[3][2] = dot(f, eye); return Result; }
然后我发现了问题所在。因为观察方向沿 y 轴,也就是 center - eye
的结果与 y 轴平行(考虑精度损失,应当是 “接近平行”),而 up
向量传入的是 cross(f, up)
的结果是一个零向量,因而 u
也变成了零向量。最坏情况下,得到的 view matrix 的几乎所有元素都是
这应该就是无法正常显示的原因了。不过,还有一个地方没弄清楚:为什么实际运行得到的值是 NaN 而不是理论上的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)