途中で色が変わる光を実現するには?


11

光源と色付きの窓を作ることを考えました。現在、ウィンドウは半透明です。どのようにすれば、光(たとえば、真っ白)がガラスに当たってそれを通過しても、通過したガラスと同じ色に色が変わるようにできますか?

ここで説明する効果は、ウィンドウの「色」側にエリアライトを使用することで偽造できることを知っていますが、1つの白色点ライトだけが必要な場合はどうなりますか?


ライトの色を変更する代わりに、ガラスの反対側にある照明されたオブジェクトのベースカラーを変更できますか?多分それはトリックをしますか?
HumanCatfood 2013

透明なウィンドウは2番目のパスとしてレンダリングされ、そのシェーダーは各ピクセル出力のカラーバランスを変更するだけです。これはうまくいきませんか?
Patrick Hughes

これは影の問題に類似しているように思えます。半透明のオブジェクトによってキャストされるシャドウに適切なアルゴリズムがある場合(それが実用的かどうかはわかりません)、3つの平行なカラーチャネルに対して実行する必要があります。
ケビンリード

回答:


14

これを行う方法は数多くあります。これらはシェーダーの使用を必要とし、私はあなたがすでにピクセルごとのライティングをしていると思います。以下はいくつかの提案ですが、適切な手法を見つけるには、さらに多くの調査が必要になる場合があります。

迅速かつ汚い

内部領域を定義する境界ボックスを指定できます。ライトがボックスの外側にあるが、ジオメトリ(シャドウにない)がボックスの内側にある場合、ライトはウィンドウを通過することによって影響を受けている必要があります(ジオメトリがボックスとライトの外側にある場合も同様です)内側にあります)。ここでの唯一の問題は、ボックス情報をシェーダーに渡す方法と、ライトへの効果をどのように述べるかです。

別のオプションは、ウィンドウを平面上にあるオブジェクトとして指定することです。最初に、ジオメトリとライトが平面の反対側にあるかどうかをテストし、次に、それらの間の道がウィンドウの境界内のポイントで平面と交差するかどうかを確認します。これは最初の方法よりも正確で、異なる色のガラスを使用して同じインテリアに窓を入れる方が簡単です。

ウィンドウの幾何学的表現をさらに詳細にしていくと、より正確な結果が得られますが、計算も重くなります。

これらのテクニックは、コリドーシューターには適度に機能しますが、アーティファクトが多すぎないように正しく調整するには多くの調整が必要になるため、ダイナミックな世界やオープンワールドにはあまり適していません。また、これらの手法はすぐに少し強くなる可能性があるため、遅延シェーディングパイプラインに移行することをお勧めします。

シャドウマップ

別のオプションは、シャドウマッピングと同様のことを行うことです。

シャドウマッピングでは、ライトの影響を受ける世界のビットマップイメージを生成します。各ピクセルはまだ色ですが、実際には最も近い不透明なジオメトリの距離です(4色ではなく、1つの浮動小数点に4バイトを使用します)。ライトからジオメトリの一部までの距離を計算し、それがシャドウマップの対応する値よりも遠い場合、ジオメトリの一部はシャドウにあります(通常、ジオメトリとライトの間のレイを使用してマップにインデックスを付けます)。

このアイデアを問題に適用する場合は、透明ジオメトリの最も近い部分のライトからの距離のマップを保存し、そのジオメトリを通過した後のライトの色の2番目のマップを作成します(ライトが白色の場合は、単にジオメトリの色)。

ジオメトリの一部がこのマップの距離よりも離れている場合は、マップの色を使用します。そうでない場合は、元の明るい色を使用します。

マップ内の各ピクセルの色を計算するための関数は、おおよそのはずです。lightColor-invertedWindowColor。したがって、純粋な白色光と、得られる赤いスペクトルをまったく吸収しない純粋な赤いウィンドウの場合。(255,255,255)-(0,255,255)=(255,0,0)。つまり、反対側の光の色は真っ赤です。ステンドグラスの窓など、より複雑な透明オブジェクトの場合は、テクスチャルックアップでマテリアルカラーを取得することができます。

同様のものが必要な場合は、反射型シャドウマップを確認してください。

この手法は忠実度が高く、ステンドグラスの窓などの複雑な透明なジオメトリを使用する場合に最適です。

一般的な解決策を試す

最近では、ボクセル表現で照明情報をエンコードすることが一般的になっています(それらはジオメトリだけではありません)。最新のcrytekエンジンは、この種の階層を使用して高度な照明(光の伝播量)を実現します。

一般的な考え方は次のとおりです。

  • シーンを囲む等間隔の立方体のマップを作成します(Zオーダーカーブの使用を検討してください)。
  • 各ボクセルの入射照明情報を保存する方法を見つけます(ここでは球面調和表現が役立ちます)。
  • ライトを含むボクセルを見つけて、そのライトをボクセルで表現します。
    • 隣接するボクセル(Minecraftの水のようなもの)を通して外側に光を伝播します
    • 各ボクセルのジオメトリが通過する光にどのように影響するかを計算します(吸収、反射、透過)。
    • 光が消えるまで繰り返します

このボクセル情報を作成する方法はたくさんありますが、上記のリストは一般的な考え方を示しています。例えば; 最初にシャドウマップ/ボリュームを生成し、その情報をボクセルマップに投影して、直接照明のマップをすばやく作成できます。次に、影響を受ける領域のエッジに沿ったボクセルから伝播を開始します。この場合、シャドウマップ/ボリュームを生成するときに、ジオメトリが透明かどうかを無視する必要があることに注意してください。

遅延レンダラーの最後のパスでは、ジオメトリのポイントのイルミネーションを計算するときに、ジオメトリの位置を使用してボクセルマップにインデックスを付け、空間内のそのポイントでの入射照明がどのようなものかを調べます。次に、インシデントライティングCPUサイドのスクリーンマップを作成するか、またはcudaを使用してこれを行うことができます。


長い投稿をありがとう!現在取り組んでいる現在のプロジェクトで、レンダリングを先送りするか延期するかを調査しています。現在、それはおそらく延期されるでしょう。ウィンドウがマルチカラー(たとえば、教会のステンドグラス)の場合、どのようにしますか?
manabreak 2013

@manabreak-シャドウマップ拡張機能を使用します。これは、その場合に最高レベルの忠実度を提供するためです。これを説明するために投稿を編集します。
OriginalDaemon

ああ、ありがとう!この投稿は本当に私の日を作りました、私はおそらく単一の投稿にそれほど多くの努力が注がれるのを見たことがありません。
manabreak 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.