2012-03-01 46 views
2

我使用VBO渲染基于数百万(最多十个)三角形的模型,并且需要检测用户可以点击哪些三角形。哪些鼠标采摘策略适用于数以百万计的基元?

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

这是我的情况最好的策略?

+1

Ray采摘与适当的边界卷层次结构也许? – Bart 2012-03-01 13:01:22

+0

名称/颜色真的很慢...我wouldnt推荐用于任何目的。只是做Bart说的。 – Rookie 2012-03-01 19:06:04

回答

8

基本上,你有2个班的选择:

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

2)适当的光线追踪。你几乎肯定希望有一个加速结构(八叉树,kd,...),但是你可能已经有一个用于平截体的选择。 One ray确实不是很多,这种方法应该非常快。

3)杂交。可能是最容易实现的。渲染出顶点缓冲区ID(“每个缓冲区的唯一颜色:),并且当你知道选择了哪个顶点缓冲区时”,只需跟踪所有三角形的光线即可。

在一般情况下,我会说2)是最好的选择。如果你想快速做一些工作,请参阅3)。 1)可能相当无用。

+0

同意。采用空间加速结构的光线追踪是最好的方法。 – kevintodisco 2012-03-02 02:12:03

+0

鉴于我对OpenGL相对比较陌生,我想从一些简单的事情开始(也许大概是^^)来实现,所以1或3 ..事实上,我主要只有一个VBO,其中包含,比方说, 10万个三角形,我想,当你提到“对所有三角形的光线”时,我很害怕这样做可能不适用于如此大量的三角形。另一件事,你有一些链接到一些很好的教程光线追踪?那么读取一个像素的深度,并将其传递给gluUnProject以检索x和y坐标? – elect 2012-03-02 07:49:02

+0

@选择,不使用名称/颜色。如果你想简化它,可以使用gluUnProject()并从任意半径处取一束三角形,并为每个三角形测试交点。但是我警告过你:根据与模型的距离/角度,你可能得不到正确的x/y位置。尽管如此,无论如何,这个方法可能需要八叉树。 – Rookie 2012-03-02 08:16:57

5

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

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

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:

保存所有trianges标识在屏幕背后,用下面的片段着色器来完成第一,我们预先计算的深度缓冲,然后用一个稍微不同的片段着色器:

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

现在我正在研究OpenGL 2.但是我很可能在近期内改变。 +1为您的有趣的职位 – elect 2012-07-31 13:02:19