我想知道如何使合并圆选择产生这种效果。以下是说明图片:
基本上我正在寻找这种效果:
如何实现圆的合并效果?我没有发现有关此效果的任何解释。我知道投射这些纹理可以开发贴花系统,但是我不知道如何创建合并效果。
如果可能的话,我正在寻找纯粹的着色器解决方案。
我想知道如何使合并圆选择产生这种效果。以下是说明图片:
基本上我正在寻找这种效果:
如何实现圆的合并效果?我没有发现有关此效果的任何解释。我知道投射这些纹理可以开发贴花系统,但是我不知道如何创建合并效果。
如果可能的话,我正在寻找纯粹的着色器解决方案。
Answers:
您可以采取一些技巧:
Z缓冲区
渲染所有其他对象后,为每个单元渲染一个较小的透明圆,最大Z值。然后在地面上渲染选择圆贴花。由于它们以Z顺序排列在下方,因此当它们以单位为单位时将被丢弃。
完全透明意味着圆仅写入Z缓冲区(最大Z值)。现在,当您渲染贴花时,它们将针对Z缓冲区值进行测试,并且如果它们通过测试,则它们将被渲染(这仅在圆之外发生)
模版
与以前的方法相同,但是这次使用模板缓冲区。为具有某些模板值的单位渲染较小的圆,然后渲染选择贴花。设置模具以丢弃带有模具值的所有元素。
例如,您可以在贴图渲染像素着色器中检查是否与任何其他贴图有交集,并在这种情况下杀死像素。进行此类圆形贴花非常有效。
您是说地面上的那些蓝色圆圈吗?
可能有一种更聪明的方法来执行此操作,但请以我的解决方案为例说明如何执行此操作。将圈子渲染为屏幕大小的单独的空纹理。此时,您可以根据需要将它们混合在一起。根据您的需要,您可以编写全色或仅写给定像素处存在圆圈的信息。但是,如果您要进行Z测试效果,则将明确需要每个写入像素的深度信息。
在上一步之后渲染地形时,可以使用像素着色器中的屏幕坐标作为UV对以前创建的纹理进行采样。现在您知道,该圆应该或不应该投影到给定的地形像素上。但是,这样可以像禁用Z测试一样工作,因此地形无法隐藏任何圆。如果希望地形隐藏其后面的圆,请在将圆与地形纹理混合之前执行深度测试。您可以使用较小的偏差来启用仅在地形下方一点的圆的渲染,但是您仍然希望它们渲染。
编辑:现在,为了获得合并圆的效果,您需要做的是:当渲染到单独的纹理时,您需要检查是否已经有一个要渲染新圆的圆。(检查那里的纹理是否有值),如果有,请擦除此像素。当两个或多个圆圈重叠时,这应具有“轮廓”效果。为了使它正常工作,但是您只需要对圆的内部而不是边界进行此测试。因此,在渲染圆时,请在输出纹理中写入一些特定的值,这表明它是一个圆。然后,您只需要在圆上不进行任何渲染就可以了。
Edit2:对于简单的红色/绿色示例:在渲染任何像素之前,请检查该像素是否尚未绿色。如果是,请不要渲染。这将达到目的。实际上,在写入纹理时,您甚至可以在圆的外部/内部使用红色/绿色,然后在渲染地形时读取这些值并将其转换为所需的颜色。
如果我的答案很抽象,请告诉我。
有一些选择。作为一种通用方法,模板缓冲区通常在需要屏蔽某些图形的地方非常方便,例如示例中圆圈重叠的轮廓。
在这种情况下,我认为无需模板缓冲区就可以轻松完成此操作。您可以使用深度缓冲区消除圆重叠的轮廓。这个想法是您将圆的内部仅绘制到深度缓冲区中(因为我们不想看到内部),然后绘制轮廓。这样,轮廓的与另一个圆重叠的部分将通过深度测试消除。
唯一的警告是您必须对深度战斗保持谨慎。您可以使用较小的偏移量来确保轮廓线实际上位于内部后面,并通过深度测试将其消除。另一种方法是使用glPolygonOffset()
。
假设您有两个平行于xy平面的圆,其圆心分别位于(x1,y1,z)和(x2,y2,z)。您具有以下绘制功能:
// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);
// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);
然后,绘图顺序如下所示,delta
只是一个小的偏移量:
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);
在我的头顶上,如果将这些贴花绘制为圆盘,我将测试每个圆与另一个圆的相交点,并将相交点放入数组中。然后绘制不在交点内的弧。但是,这不是着色器解决方案。
你想在这里嘲笑。您的第一遍将圆渲染到模板缓冲区。第二遍渲染可视轮廓,在模板缓冲区未更改的任何地方。 第二遍必须使用比第一遍更大的几何形状,在这种情况下,简单的线性标量就足够了。
尽管我在此处绘制轮廓的解决方案超出了您的需要(因为该着色器将每个网格边缘变成一个完整的四边形),但它的确遵循这种方法:将原始模型绘制到模具缓冲区中,然后在其中绘制更大的版本模具缓冲区仍为0。