数百万原始人的哪种鼠标选择策略?

时间:2012-03-01 12:43:51

标签: opengl selection jogl mouse-picking

我使用VBO渲染基于milions(最多十个)三角形的模型,我需要检测用户可以点击哪些三角形。

我尝试阅读并理解“名称堆栈”和“独特颜色”的工作原理。 我发现名称堆栈最多只能包含128个名称,而唯一颜色最多可包含2 ^(8 + 8 + 8)= 16777216种不同的颜色,但有时可能会有一些近似值,因此它可以得到改性..

对我来说,哪种策略最好?

2 个答案:

答案 0 :(得分:9)

基本上,您有两类选项:

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

  2. 正确的光线追踪。你几乎肯定想要一个加速结构(octree,kd,...),但你可能已经有一个用于截头锥体剔除。一条射线确实不是很多,这种方法应该非常快。

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

  4. 在一般情况下,我会说2)是最好的选择。如果你想快速运作,请去3)。 1)可能很没用。

答案 1 :(得分:6)

如果您的GPU卡有OpenGL 4.2,您可以使用GLSL中的imageStore()功能标记图像中的三角形ID。在我的情况下,我需要检测屏幕上预定义窗口后面的所有三角形。拣选(在窗口上选择渲染的三角形)的工作方式类似。选择对我来说是实时的。

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

可以使用此片段着色器保存屏幕后面的所有trianges:

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));
}

要保存在屏幕上呈现的所有trianges 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));
}