2014-06-26 24 views
3

我有一个3D纹理,我写数据,并且以这种方式使用它作为体素在片段着色器:写入多发3Dtextures的OpenGL

#extension GL_ARB_shader_image_size : enable 
... 
layout (binding = 0, rgba8) coherent uniform image3D volumeTexture; 
... 
void main(){ 
vec4 fragmentColor = ... 
vec3 coords = ... 
imageStore(volumeTexture, ivec3(coords), fragmentColor); 
} 

和纹理以这种方式定义

glGenTextures(1, &volumeTexture); 
glBindTexture(GL_TEXTURE_3D, volumeTexture); 
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, volumeDimensions, volumeDimensions, volumeDimensions, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 

,然后这个时候我必须使用它

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_3D, volumeTexture); 

现在我的问题是,我想甲肝这是一个mipmapped版本,并且不使用opengl函数,因为我注意到它非常慢。所以我想在同一时间在各个层次上写3D纹理,例如,最大分辨率为512^3,而且我在这个3dtex中写入了1个体素值,我还为256^3写入了0.125 * VALUE体素和0.015625 * VALUE为126^3等。因为我使用imageStore,它使用原子性所有值将被写入并使用这些权重,我会自动得到平均值(不完全像插值,但我可能会得到一个令人满意的结果无论如何)。 所以我的问题是,多个3dtextures并同时在所有这些文件中写入的最佳方式是什么?

回答

2

我相信硬件mipmapping是一样快,你会得到。我一直认为尝试自定义mipmapping会慢一些,因为您必须依次手动绑定和栅格化到每个图层。 Atomics将会引起巨大的争议,而且速度会非常慢。即使没有原子,你也会否定这个漂亮的O(log n)构造的mipmap。

您必须是真的请注意imageStore关于访问顺序和缓存。我会从这里开始尝试一些不同的索引(例如,行/列vs列/行)。

您可以尝试使用旧方法绘制纹理,将其绑定到FBO并使用glDrawElementsInstanced绘制全屏三角形(覆盖视口的大三角形)。在几何着色器中,将gl_Layer设置为实例ID。光栅化器为x/y创建碎片并且图层给出z。

最后,即使是按照今天的标准,512^3也只是一个巨大的质地。也许可以找出理论上的最大gpu带宽,以了解你有多远。例如。可以说你的GPU可以达到200GB/s。无论如何,你可能只能得到100分。你的512^3纹理是512MB,所以你可以在〜5ms内写入(imo这看起来非常快,也许我犯了一个错误)。从管道的其余部分,产卵和执行线程等方面来看,会有一些开销和延迟。如果你正在编写复杂的东西,那么内存带宽不是瓶颈,我的估计将会消失。所以试着先写第零。然后尝试更改订单号coordsxyz


更新:除了使用片段着色器来创建线程,顶点着色器可以用来代替,理论上避免了光栅化开销,虽然我已经看到了在它不执行,以及案件。您glEnable(GL_RASTERIZER_DISCARD),glDrawArrays(GL_POINTS, 0, numThreads)并使用gl_VertexID作为您的线索索引。

+0

我正在使用imageStore,因为我在一次传递中使用geom + frag(Cyril Crassin的方法)对场景进行voxelising,并且它完美地工作并以512fps(我有一个gt540m)以10fps运行。使用图像存储的原因是2个三角形可以写入相同的体素。 – tigeradol

+0

@tigeradol而不是绘制两个三角形来获得完美的四边形,绘制一个巨大的一个,只是让它被剪裁到视口(我会更新答案)。 10fps似乎不太糟糕,需要多长时间才能制作mipmap? – jozxyqk

+0

我明白了你的观点,但我不明白如果我不使用碎片着色器,我将如何在纹理内写入颜色值。关于mip地图,它下降到小于1 fps。在256^3时,它运行在29 fps(37,如果我不做阴影贴图和光照计算)并使用mipmap降到6 – tigeradol