WebGL FrameBuffer - визуализация текстуры глубины
Я нахожусь в процессе интеграции эффектов постобработки в мой 3D-движок. Я столкнулся с проблемой захвата данных о глубине с помощью объекта FrameBuffer с WebGL. Не было проблем с вводом данных о цвете в FrameBuffer. Тем не менее, я не могу получить данные о глубине, даже если расширение глубины включено для Chrome/Firefox.
var DepthEXT = webGLContext.getExtension( "WEBKIT_WEBGL_depth_texture" ) ||
webGLContext.getExtension( "MOZ_WEBGL_depth_texture" );
Я пробовал много разных настроек, чтобы увидеть, была ли это проблема с конфигурацией, но независимо от того, что я пробую, я просто вижу белую текстуру. На скриншоте в конце поста показано вложение цвета, отображаемое как текстура, и вложение глубины, отображаемое как текстура. Есть ли проблема с моей инициализацией FrameBuffer, или я должен искать в другом месте, чтобы решить эту проблему?
Ниже мой код для инициализации объекта FrameBuffer:
// Frame Buffer
this.m_frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, this.m_frameBuffer );
// Render Buffer
this.m_renderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, this.m_renderBuffer );
gl.renderbufferStorage(
gl.RENDERBUFFER,
gl.DEPTH_COMPONENT16,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height );
// Diffuse Component
this.m_diffuseComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_diffuseComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.LINEAR );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null );
// Depth
this.m_depthComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_depthComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.NEAREST );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.DEPTH_COMPONENT,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.DEPTH_COMPONENT,
gl.UNSIGNED_SHORT,
null );
// FrameBuffer
// Diffuse
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
this.m_diffuseComponentTexture,
0 );
// Depth
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D,
this.m_depthComponentTexture,
0 );
// RenderBuffer
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
this.m_renderBuffer );
// Unbind buffers and textures
gl.bindTexture( gl.TEXTURE_2D, null );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
Вот код, где я отрисовываю текущую сцену в FrameBuffer.
CBRenderer.prototype.renderSceneToGBuffer = function( sceneToRender, GBufferTarget, deltaSeconds )
{
CBMatrixStack.clearMatrixStackAndPushIdentityMatrix();
this.applyProjectionMatrix();
GBufferTarget.bindGBufferFrameBuffer();
this.renderer.enable( this.renderer.DEPTH_TEST );
this.renderer.depthMask( true );
this.renderer.clearDepth( 1.0 );
this.renderer.clearColor( 0.1, 0.1, 0.1, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
sceneToRender.render( deltaSeconds );
this.renderer.flush();
GBufferTarget.m_dirty = false;
GBufferTarget.unbindGBufferFrameBuffer();
this.renderer.clearColor( 0.0, 0.0, 0.0, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
this.renderer.bindTexture( this.renderer.TEXTURE_2D, null );
}
1 ответ
У вас нет текстуры глубины, прикрепленной к вашему FBO в конце настройки. Вы устанавливаете текстуру как привязку к глубине в некоторый момент:
// Depth
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D,
this.m_depthComponentTexture,
0 );
Но сразу после этого вы устанавливаете рендер-буфер как вложенный файл глубины:
// RenderBuffer
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
this.m_renderBuffer );
Вы можете иметь только одну цель, прикрепленную к каждой точке подключения FBO. Таким образом, второй вызов устанавливает новое вложение глубины, заменяя то, которое вы только что установили в первом вызове. Итак, в конце этого, m_depthComponentTexture
больше не привязан к FBO.
Если вы хотите использовать текстуру глубины, я не понимаю, почему вы хотели бы также создать буфер визуализации глубины. Вам нужен только один из двух. Обычно вы используете рендер-буфер для глубины, если позже он вам не понадобится. Если вы хотите сэмплировать результат, вам нужна текстура, и больше нет необходимости в рендеринг-буфере.