2017-10-03 12 views
0

私はOpenGL Multi Sample Anti Aliasingのチュートリアルを探していましたが、多くを見つけましたが、私は2をとります。OpenGL MSAAは2つの方法で動作します。違いは何ですか?

私は両方の方法をテストし、どちらも使用できるように私のプロジェクトで両方の作業を行いました。

これを使用して、ゲームエンジンのシーンをテクスチャにレンダリングします。

これが第一の方法です:

MSAA

// create a texture object 
glGenTextures(1, &textureId); 
glBindTexture(GL_TEXTURE_2D, textureId); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 
glBindTexture(GL_TEXTURE_2D, 0); 

// create a MSAA framebuffer object 
// NOTE: All attachment images must have the same # of samples. 
// Ohterwise, the framebuffer status will not be completed. 
glGenFramebuffers(1, &fboMsaaId); 
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); 

// create a MSAA renderbuffer object to store color info 
glGenRenderbuffers(1, &rboColorId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_RGB8, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// create a MSAA renderbuffer object to store depth info 
// NOTE: A depth renderable image should be attached the FBO for depth test. 
// If we don't attach a depth renderable image to the FBO, then 
// the rendering output will be corrupted because of missing depth test. 
// If you also need stencil test for your rendering, then you must 
// attach additional image to the stencil attachement point, too. 
glGenRenderbuffers(1, &rboDepthId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_DEPTH_COMPONENT, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// attach msaa RBOs to FBO attachment points 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId); 


// create a normal (no MSAA) FBO to hold a render-to-texture 
glGenFramebuffers(1, &fboId); 
glBindFramebuffer(GL_FRAMEBUFFER, fboId); 

glGenRenderbuffers(1, &rboId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboId); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// attach a texture to FBO color attachement point 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); 

// attach a rbo to FBO depth attachement point 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); 

//@@ disable color buffer if you don't attach any color buffer image, 
//@@ for example, rendering the depth buffer only to a texture. 
//@@ Otherwise, glCheckFramebufferStatus will not be complete. 
//glDrawBuffer(GL_NONE); 
//glReadBuffer(GL_NONE); 

// check FBO status 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    return false; 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 

そして、私はシーンを描画する必要がある

glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); 
glViewport(0, 0, width, height); 
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

DrawScene(); 

glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMsaaId); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); 
glBlitFramebuffer(0, 0, width, height, // src rect 
    0, 0, width, height, // dst rect 
    GL_COLOR_BUFFER_BIT, // buffer mask 
    GL_LINEAR); // scale filter 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight()); 

とFBOに第二の道を作成します。

はMSAA

unsigned int framebuffer; 
glGenFramebuffers(1, &framebuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 

// create a multisampled color attachment texture 
unsigned int textureColorBufferMultiSampled; 
glGenTextures(1, &textureColorBufferMultiSampled); 
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled); 
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE); 
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0); 

// create a (also multisampled) renderbuffer object for depth and stencil attachments 
unsigned int rbo; 
glGenRenderbuffers(1, &rbo); 
glBindRenderbuffer(GL_RENDERBUFFER, rbo); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); 

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

// configure second post-processing framebuffer 
unsigned int intermediateFBO; 
glGenFramebuffers(1, &intermediateFBO); 
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); 

// create a color attachment texture 
unsigned int screenTexture; 
glGenTextures(1, &screenTexture); 
glBindTexture(GL_TEXTURE_2D, screenTexture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer 

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << endl; 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

とFBOを作成して、私は、シーンを描画する必要がある場合:

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
glViewport(0, 0, width, height); 
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

DrawScene(); 

    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); 
    glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_LINEAR); 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight()); 

要約: 第一の方法:FBOを作成し、深さおよび使用のための色とRBOのためのRBOを作成glRenderbufferStorageMultisample(...)を入力してMSAAレベルを指定します。その後、色のテクスチャと深度のRBOを持つ他のFBOを作成します。

2番目の方法:FBOを作成し、深度の色とRBOのテクスチャを作成し、テクスチャのMSAAレベルにglTexImage2DMultisample(...)を使用します。次に、他のFBOとテクスチャを作成します。

片方向の違いは何ですか?他のものよりも優れていますか?

+1

"テクスチャとレンダバッファをfbo添付ファイルとして使用するのはどういう違いがありますか?" – BDL

+0

@BDLはい、ただしMSAAを使用している場合。相違点と一方通行が他方より優れているかどうか。 –

+1

違いはMSAAの有無にかかわらず同じです。 [this](https://www.opengl.org/discussion_boards/showthread.php/175962-FBO-Renderbuffer-vs-Texture)を読んでみてください。 – BDL

答えて

0

実際のMSAA設定は、どちらの場合でも同じです。あなたが描写した2つの方法の唯一の違いは、異なるFBOの添付ファイルタイプです。一般に、後でレンダーパスを行うために、そのFBOからの情報を後で使用する必要がある場合は、テクスチャを添付してレンダリングバッファを追加する必要があります。そのような場合は、以前のレンダーパスFBOのテクスチャアタッチメントをテクスチャユニットに差し込み、次のパスシェイダープログラムでそのサンプルをサンプリングします。 Shadow mappingはこのようなケースの1つです。

関連する問題