次の正しい方法は何ですか。
- FBO(fbo-a)を使用してシーンをテクスチャにレンダリングします
- 次に、テクスチャ(tex-a)を使用してエフェクトを適用し、同じfbo(fbo-a)を使用してこれを別のテクスチャ(tex-b)にレンダリングします。
- 次に、この2番目のテクスチャを、適用された効果(tex-b)をフルスクリーンクワッドとしてレンダリングします。
私のアプローチはこれですが、これにより、ウィンドウの「ノイズ」と適用された効果で満たされたテクスチャが得られます(すべてのピクセルはランダムに赤、緑、青、白、黒に色付けされます)。
- 2つのテクスチャがGL_COLOR_ATTACHENT0(tex-a)とGL_COLOR_ATTACHMENT1(tex-b)に設定された1つのFBOを使用しています
- fboをバインドし、glDrawBuffer(GL_COLOR_ATTACHMENT0)を使用してtex-aにレンダリングされていることを確認します
- 次に、tex-aがバインドされ、「sampler2D」として設定されたシェーダーにエフェクトを適用します。テクスチャユニット1を使用して、2番目のカラーアタッチメント(glDrawBuffer(GL_COLOR_ATTACHMENT1))に切り替えます。フルスクリーンクワッドをレンダリングします。すべてがtex-bにレンダリングされます
- 次に、デフォルトのFBO(0)に切り替え、フルスクリーンクワッドでtex-bを使用して結果をレンダリングします。
シェーダーを適用したときの結果の例
これは私が使用しているシェーダーです。これが原因である可能性があるかどうかはわかりませんが、ノイズはオーバーフローが原因である可能性がありますか?
バーテックスシェーダー
attribute vec4 a_pos;
attribute vec2 a_tex;
varying vec2 v_tex;
void main() {
mat4 ident = mat4(1.0);
v_tex = a_tex;
gl_Position = ident * a_pos;
}
フラグメントシェーダー
uniform int u_mode;
uniform sampler2D u_texture;
uniform float u_exposure;
uniform float u_decay;
uniform float u_density;
uniform float u_weight;
uniform float u_light_x;
uniform float u_light_y;
const int NUM_SAMPLES = 100;
varying vec2 v_tex;
void main() {
if (u_mode == 0) {
vec2 pos_on_screen = vec2(u_light_x, u_light_y);
vec2 delta_texc = vec2(v_tex.st - pos_on_screen.xy);
vec2 texc = v_tex;
delta_texc *= 1.0 / float(NUM_SAMPLES) * u_density;
float illum_decay = 1.0;
for(int i = 0; i < NUM_SAMPLES; i++) {
texc -= delta_texc;
vec4 sample = texture2D(u_texture, texc);
sample *= illum_decay * u_weight;
gl_FragColor += sample;
illum_decay *= u_decay;
}
gl_FragColor *= u_exposure;
}
else if(u_mode == 1) {
gl_FragColor = texture2D(u_texture, v_tex);
gl_FragColor.a = 1.0;
}
}
opengl.orgでこのFBOの記事を読みました。記事の下部に、フィードバックループが記載されています。説明は私には完全には明確ではなく、彼らがそこで説明していることを正確に行っているのだろうかと思います。
アップデート1:
アップデート2:
gl_FragColor.rgb = vec3(0.0, 0.0, 0.0);
(NUM_SAMPLESを使用して)サンプリングループを開始する前に最初に設定した場合、それは検索で機能します。理由はわかりません。