web-dev-qa-db-ja.com

フレームバッファとアクティブテクスチャの間で形成されるWebGLフィードバックループ

2パスレンダリングを使用してテクスチャにエフェクトを作成するwebglプロジェクトセットアップがあります。

最近まですべてが機能していましたchromeこのエラーをスローし始めました:

[.WebGL-0000020DB7FB7E40] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture. 

これはコードを変更していなくても発生し始めたため、新しい更新が原因で発生したと考えています。

私は この答え をSOで見つけ、「フレームバッファに現在アタッチされているテクスチャから読み取るといつでも起こります」というエラーを示しています。

しかし、私は自分のコードを100回くまなく調べており、自分がそうしているとは思いません。だからここに私が物事をセットアップする方法があります。

均一なサンプラーでフラグメントシェーダーを作成します。

uniform sampler2D sampler;

2つのテクスチャを作成する

var texture0 = initTexture(); // This function does all the work to create a texture 
var texture1 = initTexture(); // This function does all the work to create a texture 

フレームバッファーを作成する

var frameBuffer = gl.createFramebuffer();

次に、htmlイメージをtexture0にアップロードし、texture0をサンプラーにバインドすることにより、「2パス処理」を開始します。

次に、フレームバッファーをバインドし、drawArraysを呼び出します。

gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture1, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

クリーンアップするには、フレームバッファーのバインドを解除します。

gl.bindFramebuffer(gl.FRAMEBUFFER, null);

編集:

コードにブレークポイントを追加した後、nullフレームバッファーをバインドするまで実際にはエラーがスローされないことがわかりました。したがって、drawArrays呼び出しはエラーの原因ではありません。それは、後でそれをオフにするヌルフレームバッファーをバインドしています。

3
YAHsaves

Chromeはバージョン83以降、フレームバッファーとアクティブなテクスチャフィードバックループの保守的なチェックを開始しました。これらのチェックは保守的すぎる可能性が高く、実際に許可する必要のある使用法に影響します。

これらの新しいチェックでは、Chromeは、このスロットがプログラムで使用されていない場合でも、レンダーターゲットを任意のテクスチャスロットにバインドすることを禁止しているようです。

2パスレンダリングでは、おそらく次のようになります。

  1. レンダーターゲットを初期化し、フレームバッファーを指すテクスチャを作成します。
  2. ターゲットにレンダリングします。

1では、gl.bindTexture(gl.TEXTURE_2D、yourTexture)を使用してテクスチャをバインドする可能性があります。次に、ステップ2の前に、gl.bindTexture(gl.TEXTURE_2D、null)を使用してテクスチャのバインドを解除する必要があります。それ以外の場合、Chromeは、テクスチャがプログラムとしてサンプリングされていなくても、レンダーターゲットがテクスチャとしてバインドされているために失敗します。

1
Jan Wrobel