3

「リアルタイム グローバル イルミネーションのための Octree ベースのスパース ボクセル化」の一部を実装しようとしています。

基本的にボクセル化だけで、すでに完了しています。

そして、「ボクセル フラグメント リスト」構造は、基本的に、ボクセルの位置と属性の事前に割り当てられたいくつかのバッファーです。

アトミックカウンターとアトミックコンプスワップまたはアトミック追加のいずれかを使用して位置バッファーを作成するのは非常に簡単で、1つのスレッドによってのみ書き込まれるようにします

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 ビット値として格納します。

これは、アトミック カウンターのバッファー オブジェクトを記述しているように思えます。物事をシンプルに保つために (今のところ)、移動平均 (論文で説明されているように) を計算するのではなく、単純に色を合計し、レンダリング時にアクセス数で割っています。

4

1 に答える 1

3

よくわかりませんが、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 Node Subdivision のプロセスでマージされると思います。

このスレッドを送信してから何か進展があったかどうかを知りたいです。

于 2012-10-30T17:19:29.807 に答える