哪种鼠标拾取策略适用于数百万个图元



我正在使用VBO渲染基于数百万(最多十个)三角形的模型,我需要检测用户可以点击这些三角形中的哪一个。

我试着阅读并理解"名称堆栈"one_answers"独特颜色"是如何工作的。我发现名称堆栈最多只能包含128个名称,而唯一的颜色最多可以有2^(8+8+8)=16777216种可能的不同颜色,但有时可能有一些近似值,因此可以进行修改。。

哪种策略对我来说是最好的?

基本上,您有两类选项:

  1. "每个三角形唯一的颜色方式",这意味着你将一个id附加到每个三角形,并将id渲染到一个单独的渲染目标。它可以是32位的(rgb为8位,a为8位),但您可以添加第二个,以获得更多想法。获取每个三角形的id会很麻烦,但实现起来相对容易。不过(填充率)可能对性能非常不利。

  2. 正确的光线跟踪。几乎可以肯定的是,你想要一个加速结构(八叉树,kd,…),但你可能已经有了一个用于截头体剔除的结构。一条光线真的不多,这个方法应该很快。

  3. 混合动力。可能是最容易实现的。渲染出顶点缓冲区id("每个缓冲区的唯一颜色:),当您知道选择了哪个顶点缓冲区时",只需针对所有三角形跟踪光线即可。

在一般情况下,我认为2)是最好的选择。如果你想让某件事快速完成,那就去做吧。1) 可能很没用。

如果您的GPU卡具有OpenGL 4.2,则可以使用GLSL中的函数imageStore()在图像中标记三角形Id。在我的情况下,我需要检测屏幕上预定义窗口后面的所有三角形。拾取(在窗口上选择渲染的三角形)的工作原理类似。选择对我来说是实时运行的。

图像(或纹理)的最大大小应该>=8192x8192=64M。因此,它最多可以使用64M个基元(如果我们使用2、3个图像,则可以使用更多)。

保存屏幕后面的所有三角形Id可以用这个片段着色器完成:

uniform  uimage2D id_image;
void main() 
{
    color_f = vec4(0)
    ivec2 p;
    p.x = gl_PrimitiveID % 2048;
    p.y = gl_PrimitiveID / 2048;
    imageStore(id_image, p, uvec4(255));
}

要保存屏幕上渲染的所有三角形Id:首先,我们预计算深度缓冲区,然后使用稍微不同的片段着色器:

uniform  uimage2D id_image;
**layout(early_fragment_tests) in;** //the shader does not run for fragment > depth
void main() 
{
    color_f = vec4(0)
    ivec2 p;
    p.x = gl_PrimitiveID % 2048;
    p.y = gl_PrimitiveID / 2048;
    imageStore(id_image, p, uvec4(255));
}

相关内容

  • 没有找到相关文章

最新更新