You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

行主序平行投影渲染结果倒置是实现哪里出了问题?

平行投影实现异常问题

我实现了采用**行主序(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:54:15