Ich versuche eine Tiefenstruktur in einen Compute Shader zu sampeln und in eine andere Textur zu kopieren.Sample Depth Buffer im OpenGL Compute Shader
Das Problem ist, dass ich richtige Werte nicht bekommen, wenn ich aus der Tiefen Textur lesen:
Ich habe versucht, wenn die Anfangswerte der Tiefen Textur zu überprüfen, korrekt waren (mit GDebugger), und sie sind. Es ist also die imageLoad GLSL-Funktion, die falsche Werte abruft.
das ist mein GLSL Compute Shader:
layout (binding=0, r32f) readonly uniform image2D depthBuffer;
layout (binding=1, rgba8) writeonly uniform image2D colorBuffer;
// we use 16 * 16 threads groups
layout (local_size_x = 16, local_size_y = 16) in;
void main()
{
ivec2 position = ivec2(gl_GlobalInvocationID.xy);
// Sampling from the depth texture
vec4 depthSample = imageLoad(depthBuffer, position);
// We linearize the depth value
float f = 1000.0;
float n = 0.1;
float z = (2 * n)/(f + n - depthSample.r * (f - n));
// even if i try to call memoryBarrier(), barrier() or memoryBarrierShared() here, i still have the same bug
// and finally, we try to create a grayscale image of the depth values
imageStore(colorBuffer, position, vec4(z, z, z, 1));
}
und das ist, wie ich die Tiefe Textur bin zu schaffen und die Farbtextur:
// generate the deth texture
glGenTextures(1, &_depthTexture);
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, wDimensions.x, wDimensions.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// generate the color texture
glGenTextures(1, &_colorTexture);
glBindTexture(GL_TEXTURE_2D, _colorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wDimensions.x, wDimensions.y, 0, GL_RGBA, GL_FLOAT, NULL);
ich die Tiefe Textur mit Tiefenwerten füllen (Binde es an einen Bildspeicher und render die Szene) und dann rufe ich meinen compute Shader auf diese Weise:
mit:
- wDimensions = Größe des Kontextes (und der Framebuffer)
- WORK_GROUP_SIZE = 16
Sie haben keine Ahnung, warum ich gültige Tiefenwerte nicht bekommen?
EDIT:
Dies ist, was die Farbtextur aussieht, wenn ich eine Kugel machen:
IMG http://i41.tinypic.com/2rqll4l.png
und es scheint, dass glClear (GL_DEPTH_BUFFER_BIT) tut alles tun: Auch wenn ich rufe es juste vor dem glDispatchCompute() ich habe immer noch das selbe Bild ... Wie kann das möglich sein?
Zum einen: 'GL_DEPTH_COMPONENT16' ist kein Floating-Point-Bildformat. Es ist ein Fixpunkt (z.B. 'GL_R16').Es gibt nur 1 Fließkomma-Tiefen-Bildformat (gut 2, wenn Sie gepackte Tiefe + Schablone zählen) und das ist 32-Bit: 'GL_DEPTH_COMPONENT32F' –
Sie haben Recht, jetzt bekomme ich Werte, aber sie scheinen nicht gut. – Paul
* Wie kann das möglich sein? * Viele wirklich seltsame Dinge passieren, wenn Sie keine Speicherbarrieren mit Compute-Shadern verwenden. Da sie auf Speicher in einer sehr allgemeinen Weise zugreifen, ist es für den GL schwierig, Vorgänge, die vor/nach dem Compute-Shader abgeschlossen werden müssen, ordnungsgemäß zu planen und zu synchronisieren. Die normale Grafikpipeline hat eine klare Definition davon, welche Operationen abhängig sind, etc. compute shaders brechen dies völlig, da sie keine tatsächliche Stufe in der Grafikpipeline sind, sondern völlig unabhängig. –