我正在制作一个渲染动态高分辨率体素景观的程序。
目前我将体素数据存储在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以便为我处理视频内存的最佳解决方案是什么?如果有更好的方法来存储我的体素使这更容易,我会接受其他格式。
答案 0 :(得分:7)
如果您只想在着色器中访问大块内存,可以使用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
命令从中访问数据,该命令采用整数纹理坐标并忽略过滤。这当然正是你想要的。
请注意,缓冲区纹理确实有大小限制。但是,大小限制通常是视频内存的一大部分。