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

如何通过线段两端点的x/y/z坐标计算指定像素的深度值

线段深度值计算实现方案

正交投影场景(线性插值即可)

你当前的线段逻辑是沿x轴步进遍历,深度值沿线段线性变化,可直接通过插值计算:

  1. 计算总深度差 deltaz = z2 - z1
  2. 计算每一步x对应的深度步长 z_step = deltax == 0 ? 0 : (float)deltaz / deltax
  3. 遍历过程中累加步长得到当前像素的深度值,写入结构体的d字段即可,同时可添加深度测试逻辑,只有当前像素深度比缓存中已存深度更小时才更新像素值。

注意原代码的潜在问题

  • 斜率用int存储会导致小数部分被截断,线段绘制失真,建议改为float类型
  • 没有处理deltax为0的竖直线段场景,会触发除0错误
  • 缺少数组边界判断,容易访问越界崩溃
  • 初始化color数组时,所有元素的d字段需要赋值为你的深度范围最大值,保证首次绘制能正常写入

改后完整代码示例

struct distancecolor { //c = color, d = depth
    int c;
    float d;
};
distancecolor color[250][250];

void l(int x1, int y1, float z1, int x2, int y2, float z2, int cl)
{
    int deltax = x2 - x1;
    int deltay = y2 - y1;
    // 处理竖直线段特殊情况
    if (deltax == 0) {
        int y_min = y1 < y2 ? y1 : y2;
        int y_max = y1 > y2 ? y1 : y2;
        int y_count = y_max - y_min + 1;
        float z_step = (z2 - z1) / (float)(y_count - 1);
        float current_z = (y_min == y1) ? z1 : z2;
        for (int y = y_min; y <= y_max; y++) {
            if (x1 >= 0 && x1 < 250 && y >= 0 && y < 250) {
                // 深度测试:假设z越小离相机越近,可根据你的坐标系调整比较符号
                if (current_z < color[x1][y].d) {
                    color[x1][y].c = cl;
                    color[x1][y].d = current_z;
                }
            }
            current_z += z_step;
        }
        return;
    }
    float m = (float)deltay / deltax;
    float z_step = (z2 - z1) / (float)deltax;
    float current_z = z1;
    for (int x = 0; x <= deltax; x++)
    {
        float y = m * x;
        int xcalc = x + x1;
        int ycalc = round(y) + y1;
        if (xcalc >= 0 && xcalc < 250 && ycalc >=0 && ycalc <250) {
            if (current_z < color[xcalc][ycalc].d) {
                color[xcalc][ycalc].c = cl;
                color[xcalc][ycalc].d = current_z;
            }
        }
        current_z += z_step;
    }
}

透视投影场景补充说明

如果你的渲染引擎用的是透视投影,直接线性插值z会出现精度误差,需要改为对1/z做线性插值,最后再取倒数得到实际深度:

float inv_z1 = 1.0f / z1;
float inv_z2 = 1.0f / z2;
float inv_z_step = (inv_z2 - inv_z1) / (float)deltax;
float current_inv_z = inv_z1;
// 循环内计算
float current_z = 1.0f / current_inv_z;
current_inv_z += inv_z_step;

内容的提问来源于stack exchange,提问作者HippityHoppetyCodeIsMyProperty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:45:05