[OpenGL] FrameBuffer와 RenderBuffer에 대한 메모

3910 단어 GLSLWebGLOpenGL
FrameBuffer와 RenderBuffer와 같은 버퍼라는 단어는 OpenGL과 WebGL을 다루고 있다고 자주 보입니다.
어느 정도 이해하고 있습니다만, 시간을 두면 아무래도 이해가 모호해지므로, 일단 자신의 이해의 범위내에서 비망록으로서 정리했습니다.

그래서 실수나 착각이 있을지도 모릅니다. (만약 뭔가 잘못되면 지적해 주시면 기쁩니다)

Framebuffer Object



우선, FrameBuffer Object와 RenderBuffer에 대한 간단한 관계도를 썼습니다↓



보시다시피, FrameBuffer Object는 "Color Buffer""Depth Buffer""Stencil Buffer"를 포함합니다.
즉, FrameBuffer Object는 이러한 일부 버퍼를 통합하는 객체입니다.
그 자체로 값을 유지하는 것은 아닙니다. (소위 관계의 연결을 관리하는 관리자?)

Texture Buffer



그리고 실제 데이터 (픽셀 값)를 유지하는 것이 "RenderBuffer"와 "Texture Buffer"입니다.
Texture Buffer는 복수 패스로 이미지를 처리할 때 등에, 일단 텍스처에 렌더링 해, 그 후에 각종 픽셀의 값을 다른 패스로 읽어내거나 하는 것에 사용하거나 합니다.

RenderBuffer



렌더 버퍼는 그 이름과 같이 렌더링 된 결과를 보관 유지하는 버퍼입니다.
보유할 수 있는 값은 각 픽셀의 특정 값입니다. 그것이 "Color""Depth""Stencil"입니다.
즉, 렌더 버퍼를 컬러 버퍼에 연결하면 색 정보가 유지되고, 렌더링 버퍼를 깊이 버퍼에 연결하면 깊이 값이 유지된다는 것입니다.



일단 정리하면 FrameBuffer Object는 최대 3 종류의 RenderBuffer (또는 TextureBuffer)를 첨부할 수 있다는 것입니다.
세세한 것을 빼면 등장 인물은 「FrameBuffer Object」 「RenderBuffer」 「TextureBuffer」의 3개군요. 이렇게 생각하면 상당히 깔끔합니다.

그리고 RenderBuffer는 「Color Buffer」 「Depth Buffer」 「Stencil Buffer」의 어떤 역할을 담당한다고.
실제 코드 예제를 작성합니다.

렌더링 버퍼로 렌더링



renderbuffer.m
static GLuint color_render_buffer;
static GLuint depth_render_buffer;
static GLuint frame_buffer;

void InitRenderbuffer(void) {
    // カラーバッファ用レンダーバッファを生成(Generate)
    glGenRenderbuffers(1, &color_render_buffer);
    glBindRenderbuffer(GL_RENDERBUFFER, color_render_buffer);

    // デプスバッファ用レンダーバッファを生成
    glGenRenderbuffers(1, &depth_render_buffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depth_render_buffer);

    // フレームバッファを生成
    glGenFramebuffers(1, &frame_buffer);
    glBindFramebuffer(GL_FRAMEBUFFER, fraume_buffer);

    // フレームバッファにレンダーバッファを、カラーバッファとしてアタッチ
    glFramebufferRenderbuffer(GL_FRAMBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_render_buffer);

    // フレームバッファにレンダーバッファを、デプスバッファとしてアタッチ
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_render_buffer);

    // ... 中略 ...

    GLsizei count = sizeof(indices) / sizeof(indices[0]);
    glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0);
}

위는 렌더 버퍼와 프레임 버퍼의 연관을 나타내는 코드 단편입니다.
이 예에서는 렌더 버퍼로 컬러 버퍼와 깊이 버퍼를 연결합니다.glBindFramebuffer 로 프레임 버퍼를 바인드하면 이후는 바인드 된 프레임 버퍼에 렌더링됩니다. (즉, 오프 스크린 렌더링)

텍스처에 오프 스크린 렌더링



texture-rendering.m
static GLuint texture;

void InitTexture() {
    // テクスチャを生成
    glGenTexture(GL_TEXTURE_2D, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_2D_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_2D_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_2D_MAG_FLITER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_2D_MIN_FLITER, GL_LINEAR);

    // フレームバッファのカラーバッファとしてテクスチャを設定
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

    // ... 中略 ...

    GLsizei count = sizeof(indices) / sizeof(indices[0]);
    glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0);
}

중략 부분은 각종 행렬의 셋업이나 셰이더에의 데이터 송신등입니다.
요점은, glFramebufferTexture2D 함수를 사용해 프레임 버퍼에 텍스처를 첨부한 뒤, 통상의 순서로 렌더링을 실시하면(자) 텍스처에 기입해진다는 것입니다.

텍스처에 쓰여진 내용은 다음 패스에서 통상의 텍스처와 같이 텍셀을 꺼낼 수 있으므로, 그것과 합성하는 것으로 복수의 패스를 경유한 다양한 이펙트를 실현할 수 있게 된다는 것입니다.

좋은 웹페이지 즐겨찾기