web-dev-qa-db-ja.com

OpenGL FBOでマルチサンプリングを使用する方法

FBOのマルチサンプリングとアルファからカバレッジを有効にしようとしています。デフォルトのフレームバッファーを使用して、glEnable(GL_MULTISAMPLE)glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)を呼び出すだけです。しかし、自分のFBOを使用しても同じ効果を得ることができません。

私の目標:上記のプロパティを使用してデフォルトのフレームバッファに描画されるのと同じ方法で、シーンをFBOに描画します。そこから、シェーダーを通過する将来のパスのテクスチャとして画像を使用できるようにしたいと考えています。

これは機能します:マルチサンプリング/アルファからカバレッジなしでFBOを作成するためのコード、1つのカラーアタッチメント、1つの深度アタッチメント:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,defaultColorAttachment0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screenWidth,screenHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);

// Bind the texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

これは機能しません。マルチサンプルFBOを作成しようとするコード:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, defaultColorAttachment0);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, screenWidth, screenHeight, GL_FALSE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

これについてはOpenGL wikiを調べてみましたが、不完全です(さまざまな未完成の見出しがあるため、専門家ではないように見えます)。 glGetErrorは文句を言うことはありません。私はこれをいじってみましたが、黒い画面またはゴミのピクセルでいっぱいの画面が表示されます。

主な質問:マルチサンプリングとアルファからカバレッジを取得してFBOで機能させるために、どのようなことを検討/変更する必要があり、どこで(FBOの作成、テクスチャ、シェーダー)必要がありますか?

26
GraphicsMuncher

これを正しく機能させ、カラーバッファーと同じ数のサンプルを割り当てるには、マルチサンプルの深度バッファーを割り当てる必要があります。つまり、 glRenderbufferStorageMultisample (...) の代わりに glRenderbufferStorage (...) を呼び出す必要があります。

FBOは、現在割り当てられている方法で完全性チェックに失敗しています。 glCheckFramebufferStatus (...) への呼び出しは、深度バッファーに正確に1があるため、_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_を返す必要があります=サンプルとカラーバッファアタッチメントには4があります。


このFBOでマルチサンプルテクスチャアタッチメントも使用しているので、シングルサンプリングテクスチャのサンプリングとGLSLシェーダーでのマルチサンプリングの違いに注意する必要があります。

マルチサンプルテクスチャには、特別なサンプラーユニフォームタイプ(eg_sampler2DMS_)があり、整数(非正規化)テクセル座標と texelFetch (...) を使用したサンプルインデックス。これは、それらをフィルタリングしたり、ミップマップしたりできないことも意味します。

この場合、マルチサンプルテクスチャはおそらく必要ありません。MSAAをシングルサンプルFBOに解決するには、おそらく glBlitFramebuffer (...) を使用する必要があります。代わりにこれを行うと、各サンプルをフェッチしてアンチエイリアスを自分で実装する必要がなく、シェーダーでアンチエイリアス結果を読み取ることができます。

27