2013-06-09 10 views
6

Chcę przenieść inicjalizację mojej tekstury 3D z procesora na GPU. Jako test napisałem moduł cieniujący, aby ustawić wszystkie woksele na stałą wartość, ale tekstura nie jest w ogóle modyfikowana. Jak mogę to sprawić?Obliczanie modułu cieniującego bez modyfikacji tekstury 3D

obliczeniowej jednostki cieniujące:

#version 430 

layout(local_size_x=1, local_size_y=1, local_size_z=1) in; 
layout(r8, location = 0) uniform image3D volume; 

void main() 
{ 
    imageStore(volume, ivec3(gl_WorkGroupID), vec4(0)); 
} 

wywołania:

glEnable(GL_TEXTURE_3D); 
glActiveTexture(GL_TEXTURE0); 
glGenTextures(1, &volume_tid); 
glBindTexture(GL_TEXTURE_3D, volume_tid); 
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, volume_dims[0], volume_dims[1], volume_dims[2], 0, GL_RED, GL_UNSIGNED_BYTE, voxels); 

ShaderProgram computeVolumeShader; 
computeVolumeShader.loadShader(GL_COMPUTE_SHADER, "compute_volume.glsl"); 
computeVolumeShader.link(); 
computeVolumeShader.use(); 
computeVolumeShader.uniform("volume", 0); 
glBindImageTexture(0, volume_tid, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8); 
glDispatchCompute(volume_dims[0], volume_dims[1], volume_dims[2]); 
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8); 
computeVolumeShader.unUse(); 
glMemoryBarrier(GL_ALL_BARRIER_BITS); 

Uwaga: voxels doprowadza się glTexImage3D zawiera dane procesora zainicjowana.

+0

Czy próbowałeś używać prawdziwego formatu obrazu zamiast "GL_RED"? –

+0

@Nicol Kiedy używam 'GL_R8UI', nic już nie widzę, nawet bez modułu cieniującego Compute. Używam 'sampler3D' do renderowania, czy to ma znaczenie? Ponieważ "GL_RED" jest wymienione [tutaj] (http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml) w tabeli 1, myślałem, że można go używać? Mówisz o parametrze 'internalFormat', prawda? –

+0

Ale nie wiesz, co właściwie oznacza "GL_RED". To może dać ci 'GL_R8'. To może dać ci "GL_R16". Jeśli nie wybierzesz * określonego * formatu, rezygnujesz z prawa wyboru formatu. I przestało działać, gdy używałeś 'GL_R8UI', ponieważ prawdopodobnie nie ustawiłeś transferu piksela na [wstaw integralne dane zamiast znormalizowanych pływaków] (http://www.opengl.org/wiki/Pixel_Transfer#Integer_format). –

Odpowiedz

13

Ugh. Najwyraźniej tekstura 3D musi być powiązana warstwowo, w przeciwnym razie moduł cieniujący nie jest w stanie zmodyfikować żadnej współrzędnej uvw za pomocą w> 0.

glBindImageTexture(0, volume_tid, 0, /*layered=*/GL_TRUE, 0, GL_READ_WRITE, GL_R8); 

załatwia sprawę.

+0

danke schön! :) –

+1

Straciłem do tego pół dnia. Dziękuję Ci!!! Nie sądzę, żebym kiedykolwiek to rozgryzł. –

+0

Właśnie spędziłem szaloną wycieczkę przez to. To było bardzo mylące, ponieważ działało na Nvidii GM107, ale nie na GK110b (oba najnowsze sterowniki). : - / – FHoenig

Powiązane problemy