数百万原始人的哪种鼠标采摘策略?

ele*_*ect 2 opengl jogl selection mouse-picking

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

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

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

El *_*cel 9

基本上,您有两类选项:

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

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

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

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


小智 6

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

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

使用此片段着色器可以保存屏幕后面的所有trianges 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));
}
Run Code Online (Sandbox Code Playgroud)

要保存在屏幕上呈现的所有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));
}
Run Code Online (Sandbox Code Playgroud)