是什么导致一个表面与另一个表面重叠?


10

我无法真正弄清楚是什么原因导致一个表面与另一个表面重叠。在我创建的3D引擎中,我的技术在极端情况下失败了。

我的方法是从最远到最近对要绘制的表面进行排序。为了确定紧密度,我在比较平均z值。但是,有时重叠的表面的平均z值比重叠的表面。因此,距离较远的表面会被绘制在距离较近的表面上-产生如下奇怪的渲染:

大型紫色正方形,侧面有红色部分

只能看到立方体的紫色前表面,而红色的侧面涂在紫色的表面上。紫色表面的平均z值较高,因此“更远”。所以我对此技术是否正确存有疑问。

我还尝试过获取相机(即原点)到曲面的距离,但随后我需要一个点。我选择了每个表面的中间,但这似乎并不总是可行,因为并非所有表面都一样大。

因此,确定表面到原点的紧密程度的可靠方法是什么?

Answers:


11

您似乎正在尝试实现Painters算法。我猜您正在尝试从头开始编写光栅化程序作为学习练习,因为大多数现代3D硬件都使用Bart提到的内容(Z / Depth缓冲区)。为了使painters算法在所有情况下都能正常工作,您需要准备在渲染表面时细分表面以解决可能的情况(例如Wikipedia页面上显示的重叠多边形问题)。

通过从最远到最接近的渲染,您还花费时间渲染像素,这些像素以后可能会被其他多边形遮挡,当您开始在多边形上放置纹理和复杂的着色器时,这会浪费宝贵的周期。这就是现代硬件希望您从前到后进行渲染的原因,使用深度缓冲区来确定要渲染的像素是否比屏幕上的像素更远(因此可以丢弃)。

即使使用最先进的加速硬件,您仍然需要从头到尾对所有半透明的多边形进行排序和渲染,仅在渲染所有不透明多边形之后才进行渲染。


您说的很对,我正在创建一个简单的渲染器。关键是我没有使用任何3D库。我自己进行所有投影计算,然后使用2D图形库绘制线条。这不是最快的,而且我不做任何基于像素的事情。我每个表面只有4个点,并用一种​​颜色填充矩形。由于我一次要绘制一个完整的曲面,因此我是否必须要从背面绘制才正确?
pimvdb 2011年

听起来很有趣,也是一种学习的好方法。如果您不使用任何形式的深度缓冲区,则回到前面是您的唯一方法。我认为您必须计算出多边形的所有屏幕坐标,然后检查是否有重叠。如果它们在深度上重叠,则可能需要将多边形切碎以进行渲染,因此您实际上可以正确地解决排序问题。您可能还想研究背面剔除,以删除不一定可见的多边形
Roger Perkins

罗杰·珀金斯是对的。除非您将多边形切碎,否则您将无法以这种方式实现正确的z排序(这意味着您始终会有一些边缘情况)。但是,这可能会变得很慢。
bummzack 2011年

我知道了!我所做的是背面剔除和分类的组合:在一个立体立方体中,一些脸不可见,而另一些则不可见(最多3个)。所以我先画了不可见的部分,然后在它们上面画了可见的部分。这就像一种魅力,如果我移除一个或多个边,则它们是重叠的,但仍然以正确的顺序绘制。谢谢!
pimvdb 2011年

1
这仅适用于简单的凸形,例如立方体。我很高兴它目前正在为您解决,但这不是一个通用的解决方案。
理查德·法比安

3

您所拥有的是可见性问题。一种解决方案是使用z-buffer


谢谢,但是如果我没有记错的话,z缓冲需要按像素渲染。我没有这样做-我在立方体的投影点之间绘制直线。Z缓冲仍然可能吗?
pimvdb

即使绘制直线,在图像到达屏幕(或位图文件)之前的某个时刻,它也将是像素格式。
Bart van Heukelom

没错,但是我的图形库太慢了,无法以20fps进行像素渲染。不过谢谢
pimvdb

2

根据其平均z值对面进行排序是无效的,因为平均z值无法提供有关顶点甚至表面像素的实际z值的信息。

示例(警告,前面是ASCII艺术):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

有两个面A和B。从相机的角度看,A位于B的前面。但是B的平均z值较小。让我们看一下其他z值:

  • A的最小z值为4
  • A的最大z值为11
  • 因此A的平均z值为7.5
  • B的最小z值为6
  • B的最大z值为8
  • 因此B的平均z值为7

您可以尝试按它们的最小z值对它们进行排序,但在某些情况下也不可行。仅使用一个z值就无法正确地对任意面进行排序。

在Newell的算法http://en.wikipedia.org/wiki/Newell的s_algorithm中,您要做的是对z值的最小/最大范围进行排序。如果两个脸部的范围不重叠,则可以确定哪个在前面。如果他们这样做,有时您绝对必须分开面孔。有时,只要对每个顶点进行光线追踪以进行遮挡或其他某种技术就足够了。


该图是我想在他的屏幕快照中正在发生的事情的俯视图。
2011年

1

很好地学习边做边渲染。荣誉 在这种情况下,在PS1上没有“绘画算法”解决方案,而不是尝试通过排序解决问题,我们过去只是尝试将多边形彼此相邻时保持相同大小(即据我所知),和背面剔除(您没有这样做)

背面剔除是检查屏幕空间中表面法线的方向(只需从变换后的屏幕空间法线(在我们的情况下为法线的z)获取深度元素的正负号,或者是两个向量的叉积)三角形即十字(v1-v0,v2-v0))

如果实施背面剔除,还可以减少正在进行的栅格化..双赢。


感谢您的答复。我确实读过有关背面剔除的信息,但重点是我希望能够去除一侧。使用实心立方体可能效果很好,但是如果我移开一侧,则会发生咬合现象-所以我仍然需要对它们进行排序。无论如何,我想到了从原点到曲面中点发射光线的想法。如果此后光线穿过另一个表面,则第一个表面与第二个表面重叠。你能告诉我这个想法是否正确吗?谢谢!
pimvdb

尽管您的想法适用于示例案例,但在许多其他案例中,它都行不通。例如,您有一个相同的场景,但是相机倾斜了,这样不正确的渲染四边形的中心就不会重叠了。
理查德·法比安
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.