所以,首先,我不擅长计算机图形。我正在尝试实现一个GUI工具包,其中一个功能是能够将3D转换应用于2D“图层”。 (一个图层只有一个Z坐标,作为预变换,它是一个二维轴对齐的矩形)
现在,这非常简单,直到你进行3D变换将图层推回去,需要将图层分割成多个多边形才能正确渲染,如图所示。而且因为我们可以拥有透明度,所以图层可能不会被完全遮挡,同时仍需要分割。
所以这里是一个描述问题和期望结果的插图。在这种情况下,蓝色图层(称为 B )位于红色图层的顶部( R ),同时具有相同的Z位置(但 B < / strong>在 R 之后添加。在这种情况下,如果我们旋转 B ,其前两个点将获得低于0的Z指数,而底部点将获得高于0的指数(锚点是唯一的点/线)保留为0)。
有人可以建议在CPU上执行此操作的好方法吗?我一直在努力寻找适合这种情况的合适的算法实现(在C ++或C中)。
编辑: 为了澄清自己,在管道的这个阶段,还没有渲染。我们只需要为每个图层生成一组多边形,然后表示图层的变换和遮挡几何。然后,如果需要,在需要时进行渲染(软件或硬件),但情况并非总是如此(例如,在进行命中测试时)。
编辑2: 我将二进制空间分区作为实现此目的的选项,但我只能找到一个实现(在GL2PS
中) ,我不知道该怎么用。我对BSP的工作方式有一个模糊的理解,但我不确定如何将它们用于遮挡剔除。
编辑3: 我不打算在此阶段进行色彩和透明度混合。只是纯几何。透明度可以由渲染器处理,透支也可以。在这种情况下,蓝色多边形可以仅在红色多边形下绘制,但是对于更复杂的情况,可能需要深度排序或甚至分割多边形(如下所示的可怕情况的示例)。虽然视口是固定的,因为所有图层都可以在3D中变换,因此可以创建如下所示的形状。
所以我真正想要的是一种算法,它将几何分层 B 分成两个蓝色形状,其中一个将被绘制在“上方”和一个其中将在 R 下面绘制。 “下面”部分会被透支,是的,但这不是一个重大问题。所以 B 只需要分成两个多边形,这样当按顺序绘制这些多边形时,它似乎会切断 R 。无需担心混合。
编辑4: 出于此目的,我们无法渲染任何内容。这一切都必须完全以几何形式完成(生成 2D 多边形)。这就是我最初的目标。
编辑5: 我应该注意每个子场景的四边形总数约为30(平均值)。绝对不会超过100.除非图层是3D变换的(这是出现此问题的地方),它们只是在绘制之前按Z位置排序的基数。具有相同Z位置的图层按照添加顺序(先进先出)绘制。
很抱歉,如果我在原始问题中没有说清楚。
答案 0 :(得分:2)
如果你不熟悉计算机图形和#34;如果多边形可以透明,那么在CPU(软件渲染)上进行操作将非常困难。
最简单的方法是使用Depth Peeling technique的GPU渲染(OpenGL / Direct3D)。
Cpu解决方案:
Soltuion#1(非常困难):
(我忘记了这个算法的名称)。
您需要将多边形B拆分为两个,例如,使用多边形A作为剪裁平面,然后使用painter算法渲染结果。 要做到这一点,您需要更改渲染例程,以便它们不再使用四边形,而是使用纹理多边形,此外您还必须编写/调试剪切例程,以便分割三角形在场景中他们不再打破paitner的算法。
大问题:如果你有很多多边形,这个解决方案可能会将场景分成无数个三角形。另外,自己编写纹理渲染代码并不是很有趣,因此建议使用OpenGL / Direct3D。
这可能非常难以做到。我认为这种方法在&#34;计算机图形学使用OpenGL第二版&#34; by#34; Francis S. Hill&#34; - 在他们的一个练习中的某个地方。
另请查看Hidden Surface Removal上的维基百科文章。
解决方案#2(更简单):
您需要实现多层z-buffer,最多可存储N个透明像素及其深度。
解决方案#3(计算成本高昂): 只需使用ray-tracing即可。您将获得完美的渲染结果(没有深度剥离和CPU解决方案#2的限制),但它的计算成本很高,因此您需要大量优化渲染例程。
底线:
如果您正在执行软件渲染,请使用解决方案#2或#3。如果您在硬件上渲染,请使用类似于深度剥离的技术,或在硬件上实现光线跟踪。
<强> - 编辑 - 1 - 强>
实施#1和#2所需的知识是"line-plane intersection"。如果您了解如何使用平面将线条(在3d空间中)分割为两个,则可以轻松实现光线跟踪或剪切。
#2的所需知识是&#34;纹理3d三角渲染&#34; (算法)。这是一个相当复杂的话题。
为了实现GPU解决方案,您需要能够找到几个处理着色器的OpenGL教程。
<强> - 编辑 - 2 - 强>
透明度是相关的,因为为了获得正确的透明度,您需要使用画家的算法从后到前(从最远到最近)绘制多边形。正确排序多边形是impossible in certain situation,因此必须将它们拆分,或者您应该使用列出的技术之一,否则在某些情况下会出现伪像/错误渲染的图像。
如果没有透明度,您可以使用硬件OpenGL实现标准zbuffer或绘图,这是一项非常简单的任务。
<强> - 编辑 - 3 - 强>
我应该注意,每个子场景的四边形总数大约是30(平均值)。绝对不会超过100。
如果要分割多边形,它可以很容易地超过100。
有可能以这样的方式定位多边形,即每个多边形将分割所有其他多边形。
现在,2 ^ 29是536870912,但是,不可能用一个平面分割一个表面,使得在每个分割数量的多边形将加倍。如果将一个多边形分割为29个时间,则在最佳情况下您将获得30个多边形,如果分割平面不平行,则在最坏的情况下可能会有数千个多边形。
这应该有用的粗略算法大纲:
通过查看该算法,您可以轻松理解为什么现在每个人都使用Z缓冲区。
来考虑一下,这对于专攻CG的大学来说是一次很好的训练。这种运动可能会让你的学生讨厌你。
答案 1 :(得分:0)
我要说出来给出更简单的解决方案,这可能不适合你的问题。为什么不直接更改您的图稿以防止出现此问题。
在问题1中,只需在Maya或其他任何事先划分多边形。对于3线问题,再次在交叉点划分多边形以防止战斗。预先计算的解决方案总是比在飞行时更快 - 特别是在有限的硬件上。从专业经验来看,我可以说它也有规模,它可以扩展。它只需要从艺术方面和技术评论中进行一些调整,以确保“非法”创建任何内容。你可能最终得到更多的聚合物这样做而不是动态渲染,但至少你不需要对可能无法完成任务的CPU进行大量的数学计算。
如果您无法控制图稿管道,这将无法正常工作,因为编写某种转换器所需的时间比启动并运行BSP细分例程要长。不过,KISS通常是最好的解决方案。