3d - 截锥平面演算

标签 3d clipping

我正在使用 Canvas 和 box likeprimitives (à la Minecraft) 从头开始​​编写一个简单的 JavaScript 3D 引擎。我正在实现尽可能多的优化,到目前为止我有背面剔除和隐藏的面部遮挡,但我不知道如何以最佳方式进行视锥剔除。

我尝试过 2D 剔除,但有一个我无法解决的特定问题:如果 4 点平面的单个顶点在相机后面,它仍然会被绘制但完全扭曲(我认为 x 和 y 坐标是颠倒的) - 见图片。

我开始认为如果不使用更复杂的数学和渲染序列,这还没有真正的解决方案。

At first everything's ok

enter image description here

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

enter image description here

我在 OpenGL 方面有一些经验,它呈现的东西完全不同,所以这甚至不是问题。

我有机会在不拉头发的情况下修复它吗?

解决方案

最终的解决方案是在进行 2D 投影和屏幕剪辑之前,针对 3D 中的近剪裁平面测试 8 个顶点中的每一个。

这是第二个裁剪步骤,第一个步骤是使用半径为 sqrt(3/2)*boxSideLength 的边界球来测试框是否完全在裁剪平面后面。 .

额外的三角形(在这种情况下实际上是点)太复杂且数学密集,这个解决方案并不完美但非常漂亮。

最佳答案

您无法将相机后面的 3d 点投影到 2d 屏幕空间并使其有意义。所以你至少需要定义一个近平面来剪辑。在将点从世界空间转换到相机空间之后,但在投影到屏幕空间之前,您需要进行一些剪辑。您需要定义一个近平面,例如 z = 1或靠近但在相机前面的东西,并将定义一个空间,在该空间中点能够投影到屏幕空间中。

您有三个选项,第一个是如果多边形中的任何点落在近平面后面,则不要绘制整个多边形。这很简单,但通常是 Not Acceptable 。将每个点与近平面进行比较(如果 polygon.points[i].z < near.z )。但这会使多边形消失并在屏幕边缘看似随机地重新出现。

您的第二个选择是将多边形剪切到近平面。对于三角形,如果所有三个点都在近平面后面,则不要绘制。如果两个点在后面,则将两条线段剪辑到近平面并绘制三角形。如果一个点在近平面后面,则剪裁并制作两个新三角形并绘制。如果没有在近平面后面,则只需绘制。如果我不是通过手机发布此内容,我会详细介绍,但希望这是有道理的。

最后,您可以进行完整的视锥体剪裁,而不仅仅是剪裁到近平面,还可以剪裁可见视锥体的所有 6 个侧面。

这些方法中的每一种都有优化算法,但我将从基础开始并继续工作。每一步基本上都是最后一步的延伸,所以我会从第一步开始,然后变得更复杂,直到获得所需的视觉和性能水平。

关于3d - 截锥平面演算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7378632/

相关文章:

c++ - 带有立方体贴图数组的 glTextureStorage3D 上的 GL_INVALID_VALUE

c# - 基本渲染 3D 透视投影到带摄像头的 2D 屏幕(不带 opengl)

c++ - 这个 operator[] 函数的实现是如何工作的?

c++ - 具有多边形裁剪区域的 Liang Barsky 裁线算法

c# - 通过LiangBarsky算法裁剪线C#

javascript - Phaser 3 碰撞器剪辑

python - 带箭袋的 3D 矢量保持静态

javascript - 获取 A 框架中实体的方向向量

html - 将 clipPath 应用于带有变换的图像元素时出现问题

flutter 剪辑,剪辑的小部件周围没有空间