2012-09-25 3 views
3

"Octree-Based Sparse Voxelization for Real-Time Global Illumination" 부분을 구현하려고합니다.보셀에 액세스하는 다중 스레드에 대한 고유 버퍼 인덱스 얻기

기본적으로 voxelization은 이미 완료되었습니다.

그리고 기본적으로 복셀 위치와 속성의 미리 할당 된 여러 버퍼 인 "Voxel-fragment list"구성입니다.

그것의 원자 카운터와 원자-COMP-스왑 또는 하나의 경우 어디에서, 그것은 하나 개의 스레드 만

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)); 
    } 
} 

에 의해 작성하기 위해 원자는-추가하지만를 사용하여 위치 버퍼를 생성 아주 쉽게 여러 스레드가 동일한 voxel 위치에 쓰고 있습니다. 어떻게 모든 스레드가 적절한 인덱스를 얻을 수 있습니까? 위의 올바른 색인은 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); 
} 

아래 같은

뭔가. 논문에서 유일한 힌트는

입니다. (복셀 - 단편) 목록을 관리하려면 다음 사용 가능한 항목의 색인 (즉, 목록에 복셀 단편의 개수를 나타내는 카운터)을 a 다른 버퍼 객체 안에 단일 32 비트 값.

원자 카운터에 대한 버퍼 객체를 설명하는 것과 같습니다. 지금 당장은 일을 단순하게 유지하기 위해 (나는 현재 로선) 평행 평균을 계산하지 않고 단순히 색을 합산하고 렌더링 할 때 액세스 카운트로 나누었다.

답변

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 노드 세분에 다음 공정에 병합 될 것이라 생각합니다.

이 스레드를 제출 한 이후 진행 상황이 있는지 알고 싶습니다.

+1

맞습니다. 실제로 저자로부터 피드백을 받았습니다. 그의 접근 방식은 조밀 한 3D 텍스처를 사용하지 않고 대신 모든 보셀 조각에 대한 원자 계수기를 증가시키고 사전 할당 된 "보셀 조각 목록"에 추가합니다. 이는 여러 개의 "복셀 조각"이 같은 위치를 참조 할 수 있다는 것과, 말했듯이 계층 구조 생성 프로세스에서 병합된다는 의미입니다. – ragnar