3

「霧の中の穴」効果を作成しようとしています。特定の領域が表示されていないことを示すために使用する「霧」テクスチャがある背景グリッド画像が重なっています。現在表示されている領域を示す「霧」からチャンクを切り取ろうとしています。画面から霧の一部を「マスク」しようとしています。

私が求めているものを説明するのに役立ついくつかの画像を作成しました:
背景:

BG

「マスク画像」(完全な透明度は、使用する目的のために外側の縁ではなく内側にある必要があります):

マスク

霧(申し訳ありませんが、見にくいです..ほとんど透明です):

霧

最終製品として欲しいもの:

最終製品

私が試してみました:

  • Stencil-Buffer: 1 つの事実を除いて、これは完全に機能しました...「マスク」イメージのフェード透明度を保持する方法を理解できませんでした。
  • glBlendFunc: さまざまなバージョンのパラメーターと、それを使用する他の多くのメソッド (glColorMask、glBlendEquation、glBlendFuncSeparate) を試しました。この Web サイトで見つけたいくつかのパラメーターを使用することから始めまし。「glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);」を使用しました。これは私が探していたもののように見えたので...これが結果として起こったことです:(ここで何が起こっているのかを伝えるのは難しいですが...背景のグリッドを覆う霧があります.しかし、マスクは、霧の中で透明な部分であるはずなのに、完全に不透明な黒い塊になってしまいます。
    glBlendFunc の結果

以前のコード:

glEnable(GL_BLEND); // This is not really called here... It is called on the init function of the program as it is needed all the way through the rendering cycle.
renderFogTexture(delta, 0.55f); // This renders the fog texture over the background the 0.55f is the transparency of the image. 
glBlendFunc(GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); // This is the one I tried from one of the many website I have been to today.
renderFogCircles(delta); // This just draws one (or more) of the mask images to remove the fog in key places.

(もっと多くのコードを投稿したかったのですが、多くのことを試した後、古いコードが非常に雑然としていたので削除し始めました (ブロックコメントで「バックアップ」しました))

4

2 に答える 2

3

現在フレームバッファのアルファで何もしていなければ、これは実行可能です。

ステップ 1:フレームバッファのアルファがゼロにクリアされていることを確認します。したがって、glClearColor 呼び出しでは、アルファをゼロに設定する必要があります。次に、通常どおり glClear を呼び出します。

ステップ 2:「霧」を描画する前に、マスク イメージを描画します。ティムが言ったように、一度霧と混ざると元に戻すことはできません。したがって、最初にマスクデータが必要です。

ただし、マスクを特別にレンダリングする必要もあります。マスクでフレーム バッファのアルファを変更するだけです。RGBカラーを台無しにしたくありません。これを行うには、次の関数を使用しますglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)。これにより、色の RGB 部分への書き込みがオフになります。したがって、アルファのみが変更されます。

マスク テクスチャは、表示される場所がゼロで、表示されない場所が 1 つあるようです。ただし、アルゴリズムは逆を必要とするため、テクスチャを修正するかglTexEnv、アルファを効果的に反転させるモードを使用する必要があります。

このステップの後、フレーム バッファは、フォグを表示したい場所のアルファが 0 になり、フォグを表示したくない場所のアルファが 1 になるはずです。

また、マスクのレンダリング後に呼び出しを元に戻すglColorMaskことを忘れないでください。それらの色を取り戻す必要があります。

ステップ 3:フォグをレンダリングします。それは簡単です。マスキングを機能させるには、特別なブレンド モードが必要です。このように:

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_ONE);

RGB と A ブレンド部分の分離は重要です。フレームバッファのアルファを変更したくない場合 (フォグの複数のレイヤをレンダリングする場合に備えて)。

これで完了です。

于 2012-06-06T11:22:41.857 に答える
1

画面全体に霧を描くと、それを「消去」する方法がないため、現在行っているアプローチは機能しません。

固定パイプラインを使用している場合:

固定パイプラインでマルチテクスチャリング (glTexEnv) を使用して、フォグ テクスチャとサークル テクスチャを 1 つのパスで組み合わせることができます。この関数は、これまでに使用したことがないと混乱する可能性があります。おそらく、man ページを読むのに時間を費やす必要があります。フォグを glActiveTexture 0 にバインドし、マスクを glActiveTexture 1 にバインドし、マルチテクスチャリングを有効にしてから、それらを glTexEnv と組み合わせます。これに適切なパラメーターを正確に覚えていません。

シェーダーを使用している場合:

マルチテクスチャリング シェーダーを使用して、フォグ アルファを円テクスチャで乗算し (円領域のアルファをゼロにする)、この組み合わせたテクスチャを 1 回のパスで背景にブレンドします。これはおそらく概念的にはより簡単なアプローチですが、シェーダーを使用しているかどうかはわかりません。

フォグとマスクを別々のパスで描画する方法があるかどうかはわかりません。どちらも独自のアルファ値を持っているため、それらを組み合わせて正しい色の結果を得ることが難しいでしょう。

于 2012-06-06T08:17:09.840 に答える