如何检测其他面孔(从角度看不见)隐藏的3d形状的面孔?

时间:2019-01-23 08:57:49

标签: javascript three.js 3d

假设我们有一个以XYS坐标系表示的3d立方体(实际上形状可以是任何形式,可能非常复杂,但让我们从一个立方体开始),我们正在从某个遥远的点以某个角度寻找立方体正面(例如,照相机可以以与所有XYZ轴相同的角度注视立方体)。

如何以编程方式检测不可见的脸部(在此示例中,底部,左侧和背面将被隐藏)。

2 个答案:

答案 0 :(得分:1)

由于您的形状可以是任意形状,所以一种可行的方法是使用射线投射https://en.wikipedia.org/wiki/Ray_casting

基本上,您将必须在场景中投射光线(矢量)并计算这些光线与对象的交点,这可以通过简单的数学来完成。 如果光线击中的点超过一个点,您将知道第一个点是可见的,但随后的击中将在不可见的表面上。

我编写了一种路径跟踪器,该跟踪器使用此技术来检测相机可见的内容:https://github.com/jo-va/hop。 随意看看并重用一些代码!

希望有帮助。

答案 1 :(得分:1)

删除不可见三角形的简单方法称为Backface Culling。基本上是将三个3D点投影到2D屏幕上,然后在该点顺时针或逆时针排列。根据这种安排,Normal Vector会伸入屏幕或伸出屏幕。仅根据法向矢量的方向,您就可以知道是从正面还是从背面看到三角形。您只需放下从背面看到的三角形。

这是一种非常简单的方法,但是您真正要问的是不同的。如果您有凸/凹3D polyhedra,则想知道前面的三角形是否仍然可见或被相同结构的其他三角形遮挡。

这在技术上非常复杂,通常不建议这样做。看这个简单的例子:

+--------+
|        |  <-- rectangle R
+--------+


+--------+
|        |
|  +--+  |
|  |  |  |  <-- U shape
|  |  |  |
+--+  +--+

如果我们将一个覆盖到另一个,您将得到:

+--------+
|        |
|  +--+  |
|  |RR|  |  <-- RR is rectangle R looking through the U shape
|  |--|  |
+--+  +--+

在这个实际上简单的示例中,您必须计算两个多边形的交点,以查看形状U后面的矩形R是否被完全遮挡或是否仍然可见。

随着多面体的复杂性增加,确定哪些三角形可见和哪些三角形不可见所需的算法也随之增加。

换句话说:这不是一种可行的方法,除非它不是实时的,并且由于某些原因甚至与图形无关。

在CG中,您改为使用Z缓冲区并绘制 ALL 正面三角形(这意味着您事先进行了背面剔除),并将深度(Z)保留在缓冲区中。在渲染片段(认为是“像素”)时,您要检查Z是否在先前渲染的片段之上或之下,因此可以确定单个“像素”是否可见。

因此,在您绘制 ALL 三角形之前,在当前的CG硬件(GPU)上,无法实时得知三角形是否完全(部分)可见(或完全遮挡)(即60赫兹) )。

很显然,有一些算法可以在CPU上进行可见性检查(不一定实时),但是无论如何,您可以实现等效的可能性接近0。这些算法非常复杂,需要几个月的研究...

因此背面剔除是又快又脏的,可见性检查非常复杂,并且只有在使用外部工具并且Z缓冲区需要实际渲染三角形的情况下才可行,因此这不是避免绘制不必要的几何图形的优化技术。