オブジェクトがサーフェスの近くにあるときに点灯するシェーダーを作成するにはどうすればよいですか?


15

、このオーバーウォッチゲームプレイ映像、キャラクターのシールドは、他のオブジェクトのジオメトリの近くにある地域で白点灯します。

いくつかのレベルのジオメトリをクリッピングするReinhartのシールド

床、壁、柱の近くの青いシールドの白い縁に注意してください。

シールドには独自のモデルがあり、効果はシェーダーで行われると思いますが、「近さ」の概念をシェーダープログラミングに変換する方法を理解しようとしていません。


2
Unityを使用している場合、この講演は興味深いかもしれません。スライド26に始まる「交差点のハイライト」のセクションをチェック
DMGregory

そのため、答えは以下で既に説明しましたが、ここで説明している動画をご覧ください:youtube.com/watch
v

回答:


28

一般的な概要:

  1. シールドなしでシーンの深度マップを作成します。いずれにしても、透明なオブジェクトは後のパスでレンダリングされることが多いため、これを無料で効果的に取得できます。それ以外の場合、深度サンダーを使用してRTTにシーンsansシールドをレンダリングすることにより、深度マップを作成できます。

  2. 通常、シーンをレンダリングし、深度マップをシールドシェーダーに渡します。

  3. シェーダーで、シールドフラグメントの深さとシーンの深さの差を計算し、その差を使用してフラグメントの色を変更します。

デモ

その簡単なWebGLデモを作成しました。

デモのスクリーンショット

1行ずつ

フラグメントシェーダーコードを詳しく見ていきましょう。

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

すべてのフラグメントで深度マップをサンプリングします。フラグメントを画面スペース[0、width / height]から正規化された[0.0、1.0]座標に変換するために、ビューポートの次元で分割することを忘れないでください。この時点で、単にフラグメントの色をサンプリングされた深度マップピクセルに設定すると、次のようになります。

深度マップのスクリーンショット

深度マップはグレースケールであるため、任意のチャネルから値を取得できます(rここで使用しました)。

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

その後、その深度サンプルを使用して、シーンの深度とシールドフラグメントの深度の差を見つけることができます。また、深度を正規化し、[zNear、zFar](カメラの近接および遠方面)から[0.0、1.0]に移動することを忘れないでください。smoothstepこれをうまく行います。1.0 -そのような値を反転することであるsolidsDiff最小値(0.0)に- (zNear zFar)及び0.0の差が最大である場合1.0です。

solidsDepthデプスマップを作成したデプスシェーダで既に正規化されていると想定していることに注意してください。

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

その後、深度の違いに応じてシールドのアルファチャネルを変更できます。ここでは、アルファの最小値から開始し、差に近づくにつれてアルファの素晴らしい急激な増加を0.3作成します。0.0

- 0.005オフセットは、単に「交差点」太くを作るために余白を追加します。変更してみてください!

gl_FragColor = vec4(vec3(1.0), alpha);

そして最後に、そのアルファをフラグメントの色に適用します。


機能強化

湾曲したシールドを作成したり、「エネルギーシールド」の外観のためにプラズマを追加したり(デモ)、交差点だけを表示して効果を調べたりすることができます(デモ)

あなたのグラフィックカードは限界です!


ああ。俺の。おはようございます。素晴らしいチュートリアルのタイ。
ブルーバグ

5

深度マップを使用しているだけです。ワールドをレンダリングしてからシールドをレンダリングし、シールドのレンダリングされたz値と深度バッファのz値の差を取り、ピクセルをより白く染めます。


3

どのエンジンを使用しているのかわかりません。または、使用している言語。それでも、オンラインで見つけることができるもののほとんどは、探しているものを実現するために、ある環境から別の環境に移植するのは難しくありません。

そして、あなたにとって役立つオンライン資料は確かにあります。Unityに関する次のディスカッションを参照してください:http ://www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/およびこの質問UE4関連:https://answers.unrealengine。コム/質問/ 74858 /ダイナミック力場-shader.html。完全なシェーダー例えば、Redditにはかなり最近の議論から、そのシールド効果を実装し、あなたが見ることができます:https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ されないが、チュートリアルのためにまさにその上、興味のあるものに十分関連していますhttp : //www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

また、このサイトで以前に作成された3つの関連する質問へのリンクもあります。これらは、達成したいことの背後にある概念を把握するのに非常に役立ちそうです。

宇宙船シールドフレア

ゲームでスターウォーエネルギーシールドを実装する方法

Primative sphere問題を伴うXNAシールド効果

最後に、Unityとそれぞれの仮想ストアのUnreal Engineの両方にシールドシェーダーの素晴らしい実装がいくつかあります(これらのエンジンを使用している場合)。もちろん、通常は有料の資産ですが、購入後はほとんど常にオープンソースであり、頻繁に安価です。たまたまこれらのエンジンを使用していなくても、これらのアセットは、遊んだり学習したりするのに役立ちます。

それが役に立てば幸い。


これらのリンクは役立ちますが、この答えは基本的に単なるリンクであり、実際に質問に直接対処するものではありません。リンクの関連コンテンツを実際の説明に抽出することをお勧めします。
アンコ

このリンクは質問に回答するかもしれませんが、回答の重要な部分をここに含め、参照用のリンクを提供する方が良いでしょう。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- レビューから
Vaillancourt

@Anko確かに、私の悪い。私は通常、説明とリンク集を掲載していますが、今回は正しいのですが、実際の説明はありませんでした。おそらく、答えを削除します。
マンド

@AlexandreVaillancourt OPを元のソースにリダイレクトする代わりに、別のリンクからコピーアンドペーストするだけのアイデアは好きではありません。次に、質問へのコメントにリンクを追加することをお勧めします。そのような場合の問題は、役立つ資料をたくさん知っているが、コメントするには大きすぎるということです。良い説明の答えはすでにここに掲載されましたので、しかし、それでもまだ、私はこの1つだけが消去されます
MAND
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.