为什么修改相机Z轴位置不会改变glm透视投影下点的finalPositionMin.x值
核心原因
你直接读取的finalPositionMin.x是裁剪空间坐标,还没有执行透视投影必须的透视除法(除以坐标的w分量),所以不会随相机距离变化。
公式推导验证
我们可以拆解坐标变换的每一步验证这个结论:
- 基础设定:
- 相机沿世界空间Z轴放置,位置Z值为
D(初始值500),看向Z轴正方向,无旋转偏移 - 测试顶点世界坐标固定为
(-50, 50, 0),和相机的直线距离就是D
- 相机沿世界空间Z轴放置,位置Z值为
- 视图变换后得到相机空间坐标:
x_eye = -50 // X轴无相对位移 z_eye = 0 - D = -D // Z轴相对相机的坐标 - 透视投影矩阵运算得到裁剪空间坐标:
glm的perspective生成的投影矩阵满足以下计算规则:
可以看到x_clip = x_eye * [1/(aspect * tan(fovY/2))] w_clip = -z_eye = Dx_clip(也就是你打印的finalPositionMin.x)的表达式里完全没有相机距离D的参数,只有FOV会影响它的数值,和你观测到的现象完全一致。
怎么得到随相机距离变化的坐标
要得到最终对应屏幕位置的归一化设备坐标(NDC),需要对裁剪坐标做透视除法:
float ndcX = finalPositionMin.x / finalPositionMin.w;
此时计算出来的ndcX才会和相机距离D成反比:相机离物体越近(D越小),ndcX的绝对值越大,屏幕上的物体尺寸也越大,符合你的预期。
内容的提问来源于stack exchange,提问作者Summit
相关产品推荐
相关产品推荐

