Я пытаюсь пробовать текстуру глубины в вычислительный шейдер и копировать ее в другую текстуру.Пример буфера глубины в вычисляющем шейдере OpenGL
Проблема заключается в том, что я не получаю правильные значения, когда я прочитал из глубины текстуры:
Я попытался проверить, если начальные значения глубины текстуры были правильными (с GDebugger), и они. Таким образом, функция imageLoad GLSL извлекает неправильные значения.
это мой 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));
}
и это, как я создаю текстуру глубины и цвет текстуры:
// 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);
Я заполнит глубину текстуры со значениями глубины (связать его с буфером кадров и визуализировать сцену), а затем я вызываю свой вычислительный шейдер следующим образом:
_computeShader.use();
// try to synchronize with the previous pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);
// even if i call glFinish() here, the result is the same
glBindImageTexture(0, _depthTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(1, _colorTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
glDispatchCompute((wDimensions.x + WORK_GROUP_SIZE - 1)/WORK_GROUP_SIZE,
(wDimensions.y + WORK_GROUP_SIZE - 1)/WORK_GROUP_SIZE, 1); // we divide the compute into groups of 16 threads
// try to synchronize with the next pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);
с:
- wDimensions = размером контекста (и из фреймбуфера)
- WORK_GROUP_SIZE = 16
У вас есть представление о том, почему я не получаю правильные значения глубины?
EDIT:
Это то, что цвет текстуры выглядит, когда я вынести сферу:
IMG http://i41.tinypic.com/2rqll4l.png
и кажется, что glClear (GL_DEPTH_BUFFER_BIT) не делает ничего: Даже если я называю это juste перед glDispatchCompute() у меня все еще есть одно и то же изображение ... Как это возможно?
С одной стороны: 'GL_DEPTH_COMPONENT16' не формат изображения с плавающей точкой. Это фиксированная точка (например, «GL_R16').Существует только 1 формат изображения с плавающей запятой (ну, если вы считаете, что упакованная глубина + трафарет), и это 32-бит: 'GL_DEPTH_COMPONENT32F' –
Вы правы, теперь я получаю значения, но они кажутся не очень хорошими. – Paul
* Как это возможно? * Много странных вещей случается, если вы не используете барьеры памяти с вычислительными шейдерами. Поскольку они получают доступ к памяти в очень общем режиме, GL трудно правильно планировать и синхронизировать операции, которые необходимо выполнить до/после вычислительного шейдера. Обычный графический конвейер имеет четкое определение того, какие операции зависят, и т. Д. Вычислительные шейдеры полностью нарушают это, поскольку они не являются фактическим этапом в графическом конвейере, но полностью независимы. –