为访问体素的多个线程获取唯一的缓冲区索引
我试图实现“基于八叉树的实时全局照明稀疏体素化”的一部分。
基本上只是体素化,我已经完成了。
“体素片段列表”结构,基本上是几个预先分配的体素位置和属性的缓冲区。
使用原子计数器创建位置缓冲区非常简单,并且可以使用atomic-comp-swap或atomic-add来确保它仅由一个线程写入
layout(r32ui, binding = 0) uniform coherent volatile uimage3D Voxels;
layout(r32ui, binding = 1) uniform coherent volatile uimageBuffer positionBuffer;
void writeVoxels(ivec3 coord)
{
uint voxelVal = imageAtomicCompSwap(Voxels, coord, 0, 1);
if(voxelVal == 0)
{
int index = 3*int(atomicCounterIncrement(voxelCounter));
imageStore(positionBuffer, index+0, uvec4(coord.x));
imageStore(positionBuffer, index+1, uvec4(coord.y));
imageStore(positionBuffer, index+2, uvec4(coord.z));
}
}
但是,在多个线程正在写入相同的体素位置的情况下,我如何确保所有线程都能获得适当的索引? 如上所示,正确的索引仅对1个线程有效。
像下面的东西
#extension GL_NV_shader_atomic_float : require
layout(r32ui, binding = 0) uniform coherent volatile uimage3D Voxels;
layout(r32ui, binding = 1) uniform coherent volatile uimageBuffer positionBuffer;
layout(r32f, binding = 2) uniform coherent volatile imageBuffer colorBuffer;
void writeVoxels(ivec3 coord, vec3 color)
{
uint voxelVal = imageAtomicAdd(Voxels, coord, 1);
int index;
if(voxelVal == 0) //This ensure that only 1 thread performs the
{ //atomicCounterIncrement
index = 3*int(atomicCounterIncrement(voxelCounter));
imageStore(positionBuffer, index+0, uvec4(coord.x));
imageStore(positionBuffer, index+1, uvec4(coord.y));
imageStore(positionBuffer, index+2, uvec4(coord.z));
}
//Need index to be valid here
imageAtomicAdd(colorBuffer, index+0, color.x);
imageAtomicAdd(colorBuffer, index+1, color.y);
imageAtomicAdd(colorBuffer, index+2, color.z);
}
我尝试了一堆不同的方法。 这篇论文中唯一的提示是
为了管理(体素片段)列表,我们将下一个可用条目的索引(也是列表中体素片段的数量的计数器)存储为另一个缓冲对象内的单个32位值。
这听起来像它只是描述原子计数器的缓冲区对象。 为了保持简单(目前),我没有计算运行平均值(如本文所述),只需将颜色相加并在渲染时除以访问计数即可。
我不确定,但我认为你不必使用imageAtomicAdd将具有相同坐标的体素存储到相同的体素片段中。 这意味着一些不同的体素片段可能具有相同的3d坐标。
这是我的代码。
const uint VOXEL_FRAGMENT_SIZE = 3;
layout(r32ui, binding = 0) uniform coherent volatile writeonly uimageBuffer voxelFragmentBuffer;
layout(binding=0, offset=0) uniform atomic_uint voxelIndexCounter;
// ...
int voxelIndex = int(atomicCounterIncrement( voxelIndexCounter ))* VOXEL_FRAGMENT_SIZE;
imageStore( voxelFragmentBuffer, voxelIndex+0, uvec4( convIVec3ToR32UI( voxelPosition ) ) );
imageStore( voxelFragmentBuffer, voxelIndex+1, uvec4( convVec4ToRGBA8( vec4( normal*127, 2.0 ) ) ) );
imageStore( voxelFragmentBuffer, voxelIndex+2, uvec4( convVec4ToRGBA8( color*255 ) ) );
我还没有完成实现,我可能是错的,但我认为具有相同坐标的体素将在22.5.4节点细分中的下一个过程中合并。
我想知道您提交此主题后是否有任何进展。
链接地址: http://www.djcxy.com/p/37173.html上一篇: Obtaining a unique buffer index for multiple threads accessing a voxel
下一篇: Multiple textures in one shader with ZBuffer and alpha blending in 2D