【问题标题】:Transferring large voxel data to a GLSL shader将大型体素数据传输到 GLSL 着色器
【发布时间】:2012-02-19 02:14:20
【问题描述】:

我正在开发一个渲染动态高分辨率体素景观的程序。

目前我将体素数据存储在 32x32x32 块中,每个块 4 位:

struct MapData {
    char data[32][32][16];
}

MapData *world = new MapData[(width >> 5) * (height >> 5) * (depth >> 5)];

我想要做的是将它发送到我的顶点和片段着色器进行处理和渲染。我见过几种不同的方法可以做到这一点,但我不知道哪种方法最适合。

我从sampler1D 格式开始,但这会导致浮点输出介于 0 和 1 之间。我还暗示它会将其存储为每个体素 16 位。

至于统一缓冲区对象,我尝试过但未能实现。

我对所有这一切的最大担忧是不必每帧都将整个地图发送到 GPU。我希望能够加载最大为 ~256MB(1024x2048x256 体素)的地图,因此我需要能够将其全部发送一次,然后仅重新发送已更改的块。

对于我没有编写 OpenCL 来处理视频内存的最佳解决方案是什么。如果有更好的方法来存储我的体素,让这更容易,我愿意接受其他格式。

【问题讨论】:

  • 如果这是体素数据,为什么不使用 3D 纹理 (GL_TEXTURE_3D)? glTexSubImage3D 允许您替换它的子区域。

标签: c++ opengl glsl


【解决方案1】:

如果您只想在着色器中访问大块内存,您可以使用buffer texture。这显然需要半新的 GL 版本(3.0 或更高版本),因此您需要 DX10 硬件或更高版本。

这个概念非常简单。您创建一个存储数据的缓冲区对象。您可以使用典型的glGenTextures 命令创建缓冲区纹理,然后将glBindTexture 设置为 GL_TEXTURE_BUFFER 目标。然后使用glTexBuffer 将缓冲区对象与纹理相关联。

现在,您似乎希望每个体素使用 4 位。所以你的image format 需要是单通道、无符号的 8 位整数格式。你的glTexBuffer 电话应该是这样的:

glTexBuffer(GL_TEXTURE_BUFFER, GL_RUI8, buffer);

buffer 是存储体素数据的缓冲区对象。

完成后,您可以使用usual mechanisms 更改此缓冲区对象的内容。

您绑定缓冲区纹理以进行渲染,就像任何其他纹理一样。

您在着色器中使用usamplerBuffer 采样器类型,因为它是无符号整数缓冲区纹理。您必须使用texelFetch 命令来访问其中的数据,该命令采用整数纹理坐标并忽略过滤。这当然正是您想要的。

请注意,缓冲区纹理确实有大小限制。但是,大小限制通常是显存的很大一部分。

【讨论】:

  • 谢谢,usamplerBuffer 似乎正是我想要的。而且我找不到任何关于不同图像格式的文档,所以也感谢你提供的信息。
猜你喜欢
  • 1970-01-01
  • 2013-07-30
  • 2013-09-11
  • 2017-04-03
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多