2017-03-18 9 views
1

私は少しgamedevライブラリを開発しています。このライブラリの要素の1つに、Canvas(オフスクリーン描画領域)があり、OpenGLフレームバッファを使用して実装されています。これまではすべてがうまくいきました。テクスチャを生成し、それをフレームバッファに添付してレンダリングし、フレームバッファのテクスチャをTexture2Dとして使用します。OpenGL - マルチサンプルのフレームバッファに描画し、その結果を通常のテクスチャとして使用する方法は?

ライブラリにアンチエイリアスを追加したいので、Canvasでマルチサンプリングを設定したいと思います。今私は混乱しています。なぜなら、マルチサンプルテクスチャなどを使用するようにシェーダを変更する必要があることがわかっているからです。

ライブラリのコードの変更を最小限に抑えるため、フレームバッファのマルチサンプリングを有効にするにはどうすればよいですか?可能であれば、レンダリング結果を通常のTexture2Dとして使用したいだけです。

答えて

2

混乱がないことを確認するだけです。あなたはx倍の大きさのテクスチャを作成して、フィルタがその魔法をやることを望むことはできません。 GL_LINEARなどのためaverages the four texels closest to the center of the pixel being texturedです。

マルチサンプルテクスチャを作成するには、glTexImage2DMultisample()(3.2以降のコアで使用可能)を使用します。あなたはこのように設定します。

glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); 
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, width, height, false); 

これはマルチサンプルテクスチャ内のサンプルの量であるsamplesとして自明であるべきです。また、internalformatを変更してください。

テクスチャをフレームバッファに付加するには、glFramebufferTexture2D()を使用します。ただし、textargetGL_TEXTURE_2Dと設定する代わりに、GL_TEXTURE_2D_MULTISAMPLEに設定してください。

glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0); 

フレームバッファのステータスを確認してください。

シェーダでは、マルチサンプルテクスチャにアクセスするには、sampler2DMSも使用する必要があります。ただし、マルチサンプルのテクスチャは、通常のテクスチャとはかなり異なって動作します。テクスチャから読み込む場合は、texelFetch()を使用する必要があります。

したがって、マルチサンプルテクスチャからサンプルする場合は、texture()を使用することはできませんが、texelFetch()のようなものを使用する必要があります。

uniform int texSamples; 
uniform sampler2DMS tex; 

vec4 textureMultisample(sampler2DMS sampler, ivec2 coord) 
{ 
    vec4 color = vec4(0.0); 

    for (int i = 0; i < texSamples; i++) 
     color += texelFetch(sampler, coord, i); 

    color /= float(texSamples); 

    return color; 
} 

texelFetch()は、正規化された座標を取ることはありません、あなたのようなものでこれを回避できることに注意してください:あなたはさわやかなアンチエイリアス処理結果を表示したい場合は、一日の終わりに

vec2 uv = vec2(0.5, 0.5); // normalized coordinates 
ivec2 texSize = textureSize(tex, 0); 
ivec2 texCoord = ivec2(uv * texSize); 
vec4 color = textureMultisample(tex, texCoord); 

、あなたそれをスクリーンに合わせる必要があります。

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 
glDrawBuffer(GL_BACK); 
glBlitFramebuffer(0, 0, src_width, src_height, 0, 0, dst_width, dst_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 

マルチサンプルデプスバッファが必要な場合は、glRenderbufferStorageMultisample()を参照してください。

glEnable(GL_MULTISAMPLE)も確認してください。しかし、今日では、ほとんどのドライバがデフォルトで有効になっています。

興味深いかもしれないマルチサンプリングに関連する他のいくつかのスタックオーバーフロー/エクスチェンジの質問があります。精巧な答えを

+0

ありがとう!だから私が正しく理解すれば、マルチサンプルテクスチャを描画してその結果を通常のテクスチャとして使用するには、そのマルチサンプルテクスチャ(フレームバッファ)を非マルチサンプルにBlitする必要があります。それともその周りに道があるのですか? – faiface

+0

'sampler2DMS'と' texelFetch() '/' textureMultisample() 'を使うことができれば、シェーダの中の普通のテクスチャのように使うことができます。しかし、それ以外の場合、マルチサンプルテクスチャを通常のものに変換する場合は、2つのフレームバッファの間でblitする必要があります。 – Vallentin

+0

gsampler2DMSでtexture()がサポートされている理由について[here](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/texture.xhtml)で説明できますか?ドキュメントのエラー? – Bim

関連する問題