多边形 Z 排序

时间:2021-05-19 11:28:14

标签: java graphics 3d 2d rendering

我目前正在尝试编写一个仅使用多边形的仅 2D 的 3D“渲染器”。

在渲染之前,我通过计算一个 Z 值来对多边形进行排序,如下所示:

double z = (v1.getZ()+v2.getZ()+v3.getZ());

我的多边形由每三个向量 (X,Y,Z) 组成

然后我对多边形进行排序,以便我可以使用画家算法方法:

int i = 0;
for (Poly polygon : polyZSort) {
    if(polygon.getRealZ()>z) {
        break;
    }
    i++;
}
polyZSort.add(i, polygon);

渲染就这么简单:

for (Poly poly : polyZSort) {
    OVector v1 = poly.getV1();
    v1 = form.doTransform(v1);
    OVector v2 = poly.getV2();
    v2 = form.doTransform(v2);
    OVector v3 = poly.getV3();
    v3 = form.doTransform(v3);
                
    g2d.setColor(poly.getColor());

    Polygon pl = new Polygon();
    pl.addPoint(getX(v1.getX()),getY(v1.getY()));   
    pl.addPoint(getX(v2.getX()),getY(v2.getY()));   
    pl.addPoint(getX(v3.getX()),getY(v3.getY()));
                

    g2d.fillPolygon(pl);    

    // black border line
    g2d.setColor(Color.BLACK);
    g2d.drawLine(
        getX(v1.getX()), 
        getY(v1.getY()), 
        getX(v2.getX()), 
        getY(v2.getY())
    );
                
    g2d.drawLine(
        getX(v2.getX()), 
        getY(v2.getY()), 
        getX(v3.getX()), 
        getY(v3.getY())
    );
                
    g2d.drawLine(
        getX(v3.getX()), 
        getY(v3.getY()), 
        getX(v1.getX()), 
        getY(v1.getY())
    );                          
}

这有效,即使有多个立方体(但只是大部分时间): works

但是在某些位置,排序似乎是错误的: enter image description here

有人知道问题出在哪里吗? 这是“故障”视频https://vimeo.com/552355610

1 个答案:

答案 0 :(得分:1)

您遗漏了重要的步骤......这是应该如何完成的:

  1. 输入是3D三角形列表,输出是3D三角形列表

    开始时输出列表为空

  2. “2D”屏幕投影每个处理过的三角形并保留原始 z 值

    所以它仍然是 3D ,但 x,y 是屏幕位置,z 是相机坐标系中的“原始”z 值。

  3. 在投影后检查每个处理过的三角形是否与输出列表中已有的任何三角形相交。

    如果没有出现交点,那么只需将该三角形按原样添加到输出列表中即可。

    如果它确实相交,您需要重新对所有相交的三角形和新三角形进行三角剖分,以免发生相交。并将这些新三角形添加到输出列表中(同时从输出列表中删除原始相交三角形)。

    这里是 2 个重叠三角形的示例:

    retriangulation

    如您所见,它可以创建很多新三角形,并且通常新三角形与多个三角形相交,因此您需要对重叠部分的每个三角形递归执行此操作,或者首先创建所有相交三角形的列表,然后立即对它们进行三角剖分...

  4. 处理完整个场景后,按中点z值对输出列表进行Z排序

    这一步你已经完成了。

  5. 使用二维三角形渲染来渲染排序后的输出列表

    这一步你已经完成了。

如您所见,您需要一个大小取决于场景中三角形数量和重叠的缓冲区。此外,这种方法非常复杂(对于新手程序员来说不是很好的选择)并且仅适用于非常简单的场景。对于更复杂的,使用 Z 缓冲区更容易和更快。然而,该缓冲区本身还需要三角形的 3D 渲染(因此需要更多的插值和每像素条件)。如您所见,z 排序的 O(1) 而不是 O(n.log(n))

相关问题