カードゲームでカードのドロップシャドウ効果を描画するために、どのレンダリングテクニックを使用しますか?


13

どのような種類のシェーディングアルゴリズムを使用して、これらのような影を作成できますか? ここに画像の説明を入力してください

私が作っているものは似ていますが、すべてOpenGLを使用した2D描画APIで行われているため、Z座標はありません。

さらに、手自体については、次のような陰影を付けたいと思います。 ここに画像の説明を入力してください

それに近い影付きの外観を実現する方法がわかりません。

カードの数は変化するはずであり、カードはテーブルに投げられるので、どのような種類のライトマップも使用できません。

どのような種類のアルゴリズムを検討する必要があります(実行する必要があるとわかっているぼかしは別ですか?)

ありがとう

更新

2Dカードゲームを作っています。私は、カードからドロップシャドウのオフセットを少し追加します:

ここに画像の説明を入力してください

私がそれをすることを考えている方法は次のとおりです。

  • バックバッファと同じサイズのテクスチャを保持します。
  • そのテクスチャの間に合わせのカードとして暗い長方形を描きます。

  • そのテクスチャをぼかします。

  • そのテクスチャにカードを引きます。
  • カードをさらに照明します。
  • このテクスチャをバックバッファに描画します。

私の質問は:

  • これは正しい方法ですか?

  • テクスチャにレンダリングせずにそれを行う方法はあり
    ますか(バックバッファと同じ大きさのビットマップを保持します)?


  • バックバッファサイズが最大テクスチャサイズを超えないと想定しても安全ですか?(つまり、バックバッファ
    が2000x3000 であれば、
    そのサイズのビデオメモリにテクスチャを作成できると言っても安全ですか?

ありがとう


1
2番目の問題の美点:実際にそれらのカードを手に持っている場合、それは実際には不可能です。隣り合って押されたカードは、目に見えるほど互いに影を作りません。あなたがそれらの多くを保持していない限りではありません。実際にカードをその画像に描かれているように保持することはできません。これらのカードは、数ミリメートル離れているように見えます。それらは互いに平らではありません。心配する必要はありません。
ニコルボーラス

回答:


18

誰もがこの問題に複雑すぎる解決策を与えていると思います。

ここに画像の説明を入力してください

最初に、カード(またはあなたが描きたいもの)を用意します。次に、コピーを取り、黒で塗りつぶしてガウスぼかしを実行します(b)。これらはすべて、フォトショップまたはお気に入りのアートツールで行われます。

次に、ゲーム内でカードを描画する場合、まず乗法(またはアルファ)ブレンドでぼかした黒のイメージを描画し、ある方向に少しオフセットしてから、その上にカードを描画します。ボイラ。

さらにトリックを行うには、シャドウとカードレンダリングを交互に切り替えて(d)のような効果を得るか、最初にすべてのシャドウを描画してから(e)のようにカードを描画します((e)ケースでカードに色を付けて、 'まだ分離しています=)

また、影に純粋な黒(または完全なアルファ)を​​使用しないで、より微妙で透明な影を作成することをお勧めします。


2
ゲーム外でシャドウを行うための+1。さらに一歩踏み込んで、シーンにライトがある場合にシャドウの配置場所を変更することもできます。
FrenchyNZ

+1、素敵なイラスト。さらに、ケースEでは、テーブルに暗い影をレンダリングし、ステンシル付きのカードに半明るいレンダリングを使用できます。それはより複雑になりますが、効果はさらに良くなります:)
Kromsterは、サポートMonica

2

最初のものはそれほど難しくありません。カードの手にアルファチャネルをレンダリングする場合(これは、カードが入ったピクセルの黒と透明の白のように単純な場合があります)、アルファチャネルだけで任意の種類のぼかしを実行できます。それをオフセットし、それを使用してテーブルの照明を制御します。(おそらく、Zバッファがない場合は、まずアルファチャネルを画面外のどこかでレンダリングし、次にマスクでテーブルを作成してから、実際のカードをレンダリングする必要があります。)

2番目は、SSAO(画面空間アンビエントオクルージョン)に少し似ています。その手法にはZ座標が必要です。ただし、カード間にさまざまな角度がない場合(Zバッファーがない場合はこれが推測されます)、おそらくそれぞれのドロップシャドウ(最初のような)をレンダリングすることでかなり良い近似を行うことができますカード。ただし、パフォーマンスは少し複雑になる可能性があります。すべてのプレーンは、その上のすべてのプレーンに対してぼかされたアルファチャネルを必要とし、テーブルに大量のカードがある場合、かなりのレンダリングパスになる可能性があります。


SSAOは過剰です=)アニメーションの例を見ることなく、どのシャドウイングテクニックが使用されているかを知ることは非常に困難です。カードが常にその順序と間隔で並んでいる場合は、単に影を事前にレンダリングするのが最も簡単ですが、実際にゲームを見ているかどうかはわかりません。
パトリックヒューズ

0

シャドウマップを作成できませんか?シーンをfboにレンダリングします。深度値のみを保存し、シェーダーで通常の深度値チェックを実行して、シャドウをレンダリングするかどうかを確認します。


Zバッファを使用していません。「深さ」はありません。
jmasterx

0

次のプロセスは、オフスクリーンレンダーターゲットを必要としません。ただし、そうすることで、テーブルを最初に描画する必要があります。または、少なくとも、テーブルが描画される前にテーブルがカバーするピクセルには何も描画されません。また、テーブル自体が1つの単一の重複しない部分、つまりイメージであることも必要です。

また、フレームバッファーにはアルファコンポーネントが必要です。

  1. カードのグレースケール画像を取得します。エッジの周りをファジーにし、サイズを拡大する可能性があります。これはシャドウカードの画像です。これはシングルチャンネル画像です。シェーダーでこのテクスチャにアクセスするときは、アルファコンポーネントに必ず単一の値を配置する必要があります。これは、シェーダーまたは他の場所で実行できます。

    画像の0.0の値は、影がないことを意味します。画像の値が1.0の場合、シャドウの合計を意味します。つまり、完全に真っ黒です。おそらく最も暗い色として0.5程度の値が必要です。

  2. アルファがゼロに設定されるように画面をクリアします

  3. レンダリングの前に何も(またはテーブルの「下」にレンダリングされる少なくとも何かを)、各カードのために、ファジーテクスチャをレンダリングし、(同じ向きで)カードの実際の位置からのオフセット。シェーダーによるカラー出力は次のようになります。これのブレンド構成は次のとおりです(OpenGL用語では)。

    glBlendEquation(GL_MAX);

    このブレンドモードは、重なり合うシャドウが暗くなったり明るくなったりしないようにするために使用されます。それは単にそのピクセルに書き込まれた最も暗い値を取ります。それは十分に見えるはずです。

    また、カラー書き込みマスクを使用して、カラー書き込みをオフにする必要があります。

  4. テーブルをレンダリングします。その場合、ブレンドは次のように設定する必要があります。

    glBlendEquation(GL_ADD);
    glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);

制限が厳しすぎる場合は、レンダーターゲットを使用する必要があります。これは次のように行われます。

  1. 前と同じようにシャドウカードイメージを作成します。

  2. まず、影をレンダリングします。シャドウフレームバッファーをバインドします(ハードウェアがそれらのいずれかにレンダリングできる場合にのみ、シングルチャネルイメージである必要があります)。値をゼロにクリアします。

  3. カードごとに、シャドウカードの画像をレンダリングし、前と同じようにオフセットします。シェーダーは、出力カラーの4つのコンポーネントすべてに同じ値を書き込む必要があります。ブレンドモードは再びになりますglBlendEquation(GL_MAX)

  4. 通常のフレームバッファに切り替えます。影を付けたいすべてを描画します。

  5. 次に、レンダリングしたシャドウイメージでフルスクリーンクワッドを描画します。シェーダーは、シャドウイメージから取得したテクセルを出力のアルファに保存する必要があります。RGBは無関係です。ブレンドモードは次のとおりです。

    glBlendEquation(GL_ADD);
    glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);

最初の方法では、ステップ5を忘れたと思います。ブレンドを無効にして、カードをレンダリングします。また、最初の方法では、OPの2番目のスクリーンショットに見られるように、カード間シャドウを取得できないことに注意してください。
ネイサンリード

@NathanReed:自分で物事を止める方法を知っていると思った。また、質問の下の私のコメントで指摘したように、「カード間の影」は意味をなしません。
ニコルボーラス

1
実際にどのようにカードを持っているかを現実的に表しているとは限りませんが、見た目はクールです!彼らは最初のショットで行うように、それは...どちらか、テーブルの上にフロートへのカードのために本当に「メイクセンスない」
ネイサン・リード

0

ステンシルバッファーを使用します。1にクリアし(深度をクリアすると同時に)、テーブルを描画します。次に、ステンシルテストを有効にし、ぼやけた長方形のテクスチャを使用して影を描画し、ステンシルと深度が通過すると増分し、ステンシルが失敗すると何もせず、深度が失敗すると何もせず、ステンシル関数をGL_EQUAL(ref 1、マスク0xff)に設定し、ステンシルテストを無効にします。(私はこれを完全にテストしていませんが、同様のコードから派生し、正常に動作するはずです。パラメーターを微調整する必要があるかもしれませ)。その後、他のすべてを描きます。

呼び出しは次のようになります。

glEnable (GL_STENCIL_TEST);
glStencilFunc (GL_EQUAL, 1, 2);
glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);

// draw shadow textures

glDisable (GL_STENCIL_TEST);

これが問題を引き起こす可能性があるのは、わずかにオーバーラップする2つのぼやけたエッジがある場合だけです。それ以外の場合は、基本的なOpenGL 1.1が提供するもの以上に派手なものは必要なく、すべてのハードウェアで動作します(おそらく古い3DFXカードを期待します。

2番目の選択肢は、パフォーマンスが重要でないゲームで非常にうまく機能するはずで、glCopyTexSubImage2Dです。バックバッファーよりも小さなテクスチャでも機能し、すべてのハードウェアでもサポートされます(OpenGL 1.1の一部であり、Doom 3がそれを使用しているため、サポートが非常に良好であると期待できます)。

基本的なセットアップは次のようになります。

  • 色を黒にクリアします。
  • 深度書き込みを無効にします(ただし、このメソッドは深度バッファを必要としないため、使用していないため、その部分は無視できます)。
  • ビューポートをテクスチャと同じ寸法に設定します。
  • 白い塗りつぶしジオメトリとしてカードを描きます。
  • glCopyTexSubImage2Dをテクスチャに追加します。
  • ビューポートをフルウィンドウサイズに戻します。
  • 通常どおり表を描画します。
  • テクスチャをフルスクリーンブレンドクワッドとして描画し、シェーダーを使用してテクスチャをぼかし、色を反転させます。
  • 他のすべてを描きます。

それも非常にうまく機能するはずです。ステンシルバッファ方式よりも少しGPUに負荷がかかりますが、重複するケースを正しく処理します-先ほど言ったように、あなたのようなゲームは、ローエンドでもGPUのパワーを燃やすと思いますカード。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.