OpenGL доступ к DepthComponent Texture в GLSL 400
Я пытаюсь получить доступ к текстуре DepthComponent в моем шейдере GLSL версии 400.
Программа выполняет двухпроходный рендеринг. В первом проходе я рендерил всю геометрию и цвета в кадровый буфер, на котором у меня есть ColorAttachment и DepthAttachment. DepthAttachment связан следующим образом:
(Примечание: я использую C# с OpenTK, который строго типизирован, в моих примерах кода.)
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depthTexture.ID, 0);
Текстура глубины имеет внутренний пиксельный формат DepthComponent32f, пиксельный формат DepthComponent и Float как тип пикселя. Все остальные свойства имеют значения по умолчанию.
Второй проход выводит цветное изображение кадрового буфера на экран, используя следующий шейдер:
#version 400
uniform sampler2D finalImage;
in vec2 texCoords;
out vec4 fragColor;
void main(){
fragColor = vec4(texture2D(finalImage, texCoords.xy).rgb, 1.0);
}
Но теперь я хочу прочитать текстуру глубины (DepthComponent) вместо цветовой текстуры (RGBA).
Я пробовал много вещей, таких как отключение TextureCompareMode, используя shadow2DSampler с shadow2DProj(sampler, vec4(texCoords.xy, 0.0, 1.0))
или просто textureProj(sampler, vec3(texCoords.xy, 0.0))
, Но он возвращает только 1 или 0, в зависимости от того, какую конфигурацию я использую.
Чтобы убедиться, что моя глубина текстуры в порядке, я прочитал пиксели обратно в массив с плавающей точкой следующим образом:
GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);
Кажется, что все правильно, показывает мне 1,0 для пустого пространства и значения от 0,99 до 1,0 для видимых объектов.
Редактировать Вот пример кода, как выглядит мой процесс:
Код инициализации
depthTexture= new GLEXTexture2D(width, height);
depthTexture.TextureCompareMode = TextureCompareMode.None;
depthTexture.CreateMutable(PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float);
***CreateMutable Function***
ReserveTextureID();
GLEX.glBeginTexture2D(ID);
GL.TexImage2D(TextureTarget.Texture2D, 0, pInternalFormat, width, height, 0, pFormat, pType, IntPtr.Zero);
ApplyOptions();
MarkReserved(true);
GLEX.glEndTexture2D();
(Приложение Framebuffer, упомянутое выше)
Визуализация прохода 1
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawBuffer.ID);
GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.ClearColor(Color.Gray);
GL.UseProgram(geometryPassShader.ID);
geometry_shaderUniformMVPM.SetValueMat4(false, geometryImageMVMatrix * geometryImageProjMatrix);
testRectangle.Render(PrimitiveType.QuadStrip);
GL.UseProgram(0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
Визуализация прохода 2
GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
GL.ClearColor(Color.White);
GL.UseProgram(finalImageShader.ID);
GL.ActiveTexture(TextureUnit.Texture0);
depthTexture.Bind();
final_shaderUniformMVPM.SetValueMat4(false, finalImageMatrix);
screenQuad.Render(PrimitiveType.Quads);
GL.UseProgram(0);
GL.BindTexture(TextureTarget.Texture2D, 0);
1 ответ
Через несколько часов я нашел решение. Проблема была в Минфильтре. Как группа Хронос сказала на glTexParameter:
Начальная стоимость
GL_TEXTURE_MIN_FILTER
являетсяGL_NEAREST_MIPMAP_LINEAR
,
Я изменил MinFilter моей глубины текстуры на GL_NEAREST
(где GL_LINEAR
также допустимо) и теперь значения глубины в шейдере GLSL верны (после линеаризации, конечно).
Дополнительная информация: Есть несколько расширений для MagFilter, таких как LINEAR_DETAIL_ALPHA_SGIS
, Я пробовал некоторые из них, правильность значения глубины не пострадала.