2

我最近一直在研究一个点云播放器,它应该能够理想地可视化来自激光雷达捕获的地形数据点,并以大约 30fps 的速度顺序显示它们。然而,我似乎遇到了 PCI-e IO 的问题。

我需要为每一帧加载一个存储在内存中的大点云,然后根据高度计算颜色图(我使用类似于 matlab 的喷射图),然后将数据传输到 GPU。这适用于点数 < 100 万的云捕获。然而,在大约 200 万个点处,这开始减慢到每秒 30 帧以下。我意识到这是很多数据(每点 200 万帧 * [每点 3 个浮点数 + 每个色点 3 个浮点数] * 每个浮点数 4 字节 * 每秒 30 帧 =大约每秒 1.34 GB

我的渲染代码现在看起来像这样:

glPointSize(ptSize);
glEnableClientState(GL_VERTEX_ARRAY);
if(colorflag) {
    glEnableClientState(GL_COLOR_ARRAY);
} else {
    glDisableClientState(GL_COLOR_ARRAY);
    glColor3f(1,1,1);
}
glBindBuffer(GL_ARRAY_BUFFER, vbobj[VERT_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, vertData, GL_STREAM_DRAW);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbobj[COLOR_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, colorData, GL_STREAM_DRAW);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_POINTS, 0, numPoints);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

vertData 和 colorData 的指针每帧都会改变。

我希望能够以每秒至少 30 帧的速度播放,即使稍后使用可能达到每帧 700 万点的大型点云。这甚至可能吗?或者也许将它们网格化并构建一个高度图并以某种方式显示它会更容易?我对 3-D 编程还是很陌生,所以任何建议都将不胜感激。

4

5 回答 5

7

如果可以,请使用 1D 纹理实现颜色映射。您只需要 1 个纹理坐标而不是 3 种颜色,它也会使顶点 128 位对齐。

编辑:您只需要从您的颜色图创建纹理并使用 glTexCoordPointer 而不是 glColorPointer (当然,在 [0, 1] 范围内更改纹理坐标的顶点颜色值)。这是线性插值的 6 texel 颜色图:

// Create texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Load textureData
GLubyte colorData[] = {
    0xff, 0x00, 0x00,
    0xff, 0xff, 0x00,
    0x00, 0xff, 0x00,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0xff,
    0xff, 0x00, 0xff
};
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 6, 0, GL_RGB, GL_UNSIGNED_BYTE, colorData);
glEnable(GL_TEXTURE_1D);
于 2010-08-02T23:32:07.763 回答
4

我对opengl一无所知,但是数据压缩在这里不是一种自然的解决方法吗?不支持整数类型或 16 位浮点数吗?除了每点 3 个浮点数之外,还有其他颜色表示吗?

于 2010-08-02T23:05:34.257 回答
3

如果您愿意处理延迟,您可以加倍(或更多!)缓冲您的 VBO,将几何图形传输到一个缓冲区,同时从另一个缓冲区渲染:

while(true)
{
    draw_vbo( cur_vbo_id );
    generate_new_geometry();
    load_vbo( nxt_vbo_id );
    swap( cur_vbo_id, nxt_vbo_id );
}

编辑:您也可以尝试交错顶点而不是每个组件使用一个 VBO。

于 2010-08-03T00:19:24.767 回答
1

你说它是 I/O 绑定的。这意味着您已经对其进行了概要分析,并看到它花费了 50% 或更多的时间等待 I/O。

如果是这样,那就是您必须关注的内容,而不是图形。

如果不是,那么其他一些答案对我来说听起来不错。无论如何,个人资料,不要猜测这是我使用的方法。

于 2010-08-03T01:05:31.113 回答
0

一些指示:

  • 在显卡上存储尽可能多的数据并仅加载真正需要的数据(非常明显)
  • 在树(kd- 或 octtrees)中使用 lod 级别并尽可能多地预先计算
  • 为了克服 io 瓶颈,磁盘上的压缩也很有用
于 2010-08-03T12:21:54.793 回答