我正在从头开始编写一个简单的JavaScript 3D引擎,使用Canvas和像原始文件一样的盒子(例如Minecraft).我正在实施尽可能多的优化,到目前为止,我已经背面剔除和隐藏面部遮挡,但我无法弄清楚如何做截头剔除最佳方式.
我已经尝试过2D剔除,但这有一个我无法解决的具体问题:如果一个4点平面的单个顶点出现在相机后面,它仍然被绘制但完全失真(我认为x和y坐标是相反的) - 看图像.
我开始认为如果不使用更复杂的数学和渲染序列,这还没有真正的解决方案.


我试图限制2D屏幕内的顶点x和y坐标,只要4个顶点中至少有一个仍在屏幕内(见下文),但这完全扭曲了方形面(虽然我想我可以去更多花哨的数学和其他三角形).

我有一些OpenGL的经验,它完全不同的东西,所以这甚至不是一个问题.
我有没有机会在不拔头发的情况下修理它?
最终的解决方案是在进行2D投影然后进行屏幕剪裁之前,在3D中针对近剪裁平面测试8个顶点中的每一个.
这是第二个剪切步骤,第一个是使用半径的边界球来测试框是否完全位于剪切平面的后面sqrt(3/2)*boxSideLength.
额外的三角形(在这种情况下实际上是点)太复杂和数学密集,这个解决方案并不完美但非常漂亮.
您无法将相机后面的 3D 点投影到 2D 屏幕空间中并使其有意义。因此您需要至少定义一个要剪辑的近平面。将点从世界空间转换到相机空间之后,但在投影到屏幕空间之前,您需要进行一些剪辑。您需要定义一个近平面,类似于z = 1或接近但位于相机前面的平面,并且定义一个空间,其中的点能够投影到屏幕空间中。
您有三个选择,第一个是如果多边形中的任何点落在近平面后面,则不要绘制整个多边形。这很简单,但通常是不可接受的。将每个点与近平面进行比较(如果polygon.points[i].z < near.z)。但这会使多边形消失并看似随机地重新出现在屏幕边缘。
您的第二个选择是将多边形裁剪到近平面。对于三角形,如果所有三个点都位于近平面后面,则不要绘制。如果两个点在后面,则将两条线段剪裁到近平面并绘制三角形。如果一个点位于近平面后面,则剪裁并制作两个新三角形并绘制。如果没有人在近平面后面,那么就画图。如果我不是通过手机发布此内容,我会详细说明,但希望这是有意义的。
最后,您可以进行完整的截锥体剪切,而不是仅仅剪切到近平面,而是剪切可见截锥体的所有 6 个边。
每一种方法都有优化算法,但我会从基础开始并继续努力。每个步骤基本上都是最后一个步骤的扩展,因此我将从第一个步骤开始,然后变得更加复杂,直到获得所需的视觉和性能水平。