行主序平行投影渲染结果倒置是实现哪里出了问题?
平行投影实现异常问题
我实现了采用**行主序(Row major)**存储的平行投影,投影矩阵示意如下:
在应用投影变换前,我使用复合变换矩阵对原始顶点执行坐标变换:
编辑:修正后的正确矩阵:由Z轴旋转、Y轴旋转、X轴旋转、Z轴高度缩放四个基础变换矩阵按顺序相乘得到。
矩阵参数说明:
a:绕Z轴的旋转角度b:绕Y轴的旋转角度g:绕X轴的旋转角度s:线框高度的缩放系数
当前代码运行输出的错误渲染结果如下:
预期的正确输出效果如下(图片未做居中处理):
相关参数配置:
- 近裁剪面
n=0.1 - 远裁剪面
f=100 - 坐标原点设置在线框中心,线框42单位的高度沿+Z方向延伸
实现的矩阵与向量乘法代码如下:
typedef struct s_point { float x; float y; float z; int c; // 顶点颜色 } t_point; void multiply_matrix_vector(t_point *i, t_point *o, t_pmatrix *m) { float w; o->x = i->x * m->m[0][0] + i->y * m->m[1][0] + i->z * m->m[2][0] + m->m[3][0]; o->y = i->x * m->m[0][1] + i->y * m->m[1][1] + i->z * m->m[2][1] + m->m[3][1]; o->z = i->x * m->m[0][2] + i->y * m->m[1][2] + i->z * m->m[2][2] + m->m[3][2]; w = i->x * m->m[0][3] + i->y * m->m[1][3] + i->z * m->m[2][3] + m->m[3][3]; if (w != 0.0f) { o->x /= w; o->y /= w; o->z /= w; } o->c = i->c; }
问题根因
代码存在两个核心错误,直接导致投影结果异常:
- 齐次坐标处理错误:4x4矩阵变换针对齐次坐标下的4维顶点,空间位置点的w分量固定为1。但你定义的顶点结构体只有x/y/z三个分量,计算w值时没有加上输入顶点w=1对应的常数项,相当于默认所有输入顶点w=0,把位置点当成了方向向量做变换,坐标计算基准完全错误。
- 矩阵索引与存储顺序不匹配:你明确使用行主序存储矩阵,但乘法实现中的行列索引用反。行主序下
m[i][j]代表第i行第j列的元素,若采用列向量右乘矩阵的计算方式,输出分量需要取矩阵对应列的元素与输入分量相乘,你当前的取数逻辑相当于对变换矩阵做了一次转置,旋转、缩放的变换方向全部偏移。
额外逻辑错误:平行投影变换后w分量恒为1,不需要执行透视投影里的除以w操作,多余的除法步骤在前面w计算错误的前提下,会进一步放大坐标扭曲。
内容的提问来源于stack exchange,提问作者MiguelP
相关产品推荐
相关产品推荐

