延迟渲染 - Renderbuffer vs Texture

Joa*_*cho 2 opengl deferred-rendering

所以,我一直在读这个,我还没有得出结论.一些例子使用纹理作为渲染目标,有些人使用渲染缓冲区,有些人同时使用它们!

例如,仅使用纹理:

// Create the gbuffer textures
glGenTextures(ARRAY_SIZE_IN_ELEMENTS(m_textures), m_textures);
glGenTextures(1, &m_depthTexture);

for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_textures) ; i++) {
    glBindTexture(GL_TEXTURE_2D, m_textures[i]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
}
Run Code Online (Sandbox Code Playgroud)

都:

glGenRenderbuffersEXT ( 1, &m_diffuseRT );
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT, m_diffuseRT );
glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT, GL_RGBA, m_width, m_height );
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_diffuseRT );
glGenTextures ( 1, &m_diffuseTexture );
glBindTexture ( GL_TEXTURE_2D, m_diffuseTexture );
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
// Attach the texture to the FBO
glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_diffuseTexture, 0 );
Run Code Online (Sandbox Code Playgroud)

有什么不同?创建纹理,渲染缓冲区然后将其分配给另一个是什么意义?成功为图像提供纹理后,它的内存已分配,那么为什么需要将它绑定到渲染缓冲区?为什么会使用纹理或渲染缓冲区?有什么好处?

我读过你不能从renderbuffer中读取,只能读取纹理.什么是它的使用呢?

编辑:所以,我目前的GBuffer代码是这样的:

    enum class GBufferTextureType
        {
        Depth = 0,
        Position,
        Diffuse,
        Normal,
        TexCoord
        };
Run Code Online (Sandbox Code Playgroud)

...

glGenFramebuffers ( 1, &OpenGLID );
if ( Graphics::GraphicsBackend->CheckError() == false )
    {
    Delete();
    return false;
    }

glBindFramebuffer ( GL_FRAMEBUFFER, OpenGLID );
if ( Graphics::GraphicsBackend->CheckError() == false )
    {
    Delete();
    return false;
    }

uint32_t TextureGLIDs[5];
glGenTextures ( 5, TextureGLIDs );
if ( Graphics::GraphicsBackend->CheckError() == false )
    {
    Delete();
    return false;
    }

// Create the depth texture
glBindTexture ( GL_TEXTURE_2D, TextureGLIDs[ ( int ) GBufferTextureType::Depth] );
glTexImage2D ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, In_Dimensions.x, In_Dimensions.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );
glFramebufferTexture2D ( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, TextureGLIDs[ ( int ) GBufferTextureType::Depth], 0 );

// Create the color textures
for ( unsigned cont = 1; cont < 5; ++cont )
    {
    glBindTexture ( GL_TEXTURE_2D, TextureGLIDs[cont] );
    glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB32F, In_Dimensions.x, In_Dimensions.y, 0, GL_RGB, GL_FLOAT, NULL );
    glFramebufferTexture2D ( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + cont, GL_TEXTURE_2D, TextureGLIDs[cont], 0 );
    }

// Specify draw buffers
GLenum DrawBuffers[4];
for ( unsigned cont = 0; cont < 4; ++cont )
    DrawBuffers[cont] = GL_COLOR_ATTACHMENT0 + cont;

glDrawBuffers ( 4, DrawBuffers );

if ( Graphics::GraphicsBackend->CheckError() == false )
    {
    Delete();
    return false;
    }

GLenum Status = glCheckFramebufferStatus ( GL_FRAMEBUFFER );
if ( Status != GL_FRAMEBUFFER_COMPLETE )
    {
    Delete();
    return false;
    }

Dimensions = In_Dimensions;

// Unbind
glBindFramebuffer ( GL_FRAMEBUFFER, 0 );
Run Code Online (Sandbox Code Playgroud)

这是要走的路吗?我还是要编写相应的着色器......

Nic*_*las 6

创建纹理,渲染缓冲区然后将其分配给另一个是什么意义?

那不是正在发生的事情.但这没关系,因为第二个示例代码是错误的废话.该glFramebufferTexture2DEXT被覆盖从绑定glFramebufferRenderbufferEXT.渲染缓冲区在创建后实际上从未使用过.

如果您在某处找到了代码,我强烈建议您忽略源代码告诉您的有关OpenGL开发的任何内容.虽然我无论如何都会建议,因为它在2016年使用了"EXT"扩展功能,自核心FBO推出以来差不多十年了.

我读过你不能从renderbuffer中读取,只能读取纹理.什么是它的使用呢?

这完全是他们的一点:你使用你的图像渲染一个希望从阅读.这对延迟渲染没有用,因为你真的想从中读取它们.

但想象一下,如果您要生成场景的反射图像,稍后您将在主场景中将其用作纹理.那么,要渲染反射场景,您需要一个深度缓冲区.但是你不会从那个深度缓冲区读取(不管是纹理,无论如何); 你需要一个深度缓冲来进行深度测试.但是你要读的唯一图像是彩色图像.

因此,您可以将深度缓冲区设为渲染缓冲区.这告诉实现可以将图像放入任何最有效用作深度缓冲区的存储器中,而不必担心回读性能.这可能会也可能不会对性能产生影响.但至少,它不会比使用纹理慢.