利用に関して

掲載記事は個人的な見解・理解を多く含み、確実に正規な情報ではないことがあります。
このサイト閲覧・利用に伴う損害等の免責は負いません。

2018年12月21日金曜日

UnityでアレのAoEっぽいものを作る


あれのAoEっぽいシェーダー

シェーダーについて勉強していた時の話
円をシェーダーで描く項目をやって円を描いてみたのです


そして次に思ったのが
”メッシュに図形を書き加えられるなら[とあるゲーム]のAoEっぽいの作れるんじゃ?”
そんな出来心スタートです。

http://nn-hokuson.hatenablog.com/entry/2016/11/14/203745

こちらを参考にすると円を表示させてスクロールさせることまでできます。



AoEを実現するにはそこから
・円の原点を任意に変えられるようにする
・任意のメッシュ上にこのシェーダーを適用できるようにする

が出来たら実装できそう

任意のメッシュ上にシェーダーを適用させる

こちらはどうやって実装しようか悩んだところです。
いろいろ考えた結果、投影することにしました。
投影の計算式はまぁ複雑なのですがUnityでは投影をやってくれるコンポーネントがあるのでそれを使います。

Projectirコンポーネント
ここにセットされたマテリアルを投影してくれます。



位置を動的に変更する

円の原点を任意に変える

これは
「シェーダー」
void surf(Input IN, inout SurfaceOutputStandard o) {
 float dist = distance(float4(0,0,0,0), IN.worldPos);

の”float4(0,0,0,0)”を

「シェーダー」
void surf(Input IN, inout SurfaceOutputStandard o) {
    float dist = distance(_Center, IN.worldPos);

プロパティの変数”_Center”にして、スクリプトから設定してあげることで実現できます。

ProjectorがアタッチされているtransformのpositionをShaderに渡します
「スクリプト」
_AoEmaterial.SetVector(_AoES_CenterID, this.transform.position);

これでShaderの円の中心がオブジェクトの場所になります

円の範囲を制限する

このままでは無限に範囲が表示されるので描画範囲を制限します

「シェーダー」
if (dist < _Range) {
    o.Albedo = _AoEColor;
    =中略=
   }
   else {
    o.Albedo = fixed4(0,0,0,0);
    o.Alpha = 0;
   }
}


半径を設定してそれ以外は透明で描画するようにします

ぬぺっとした円が描画されます

AoEは加算合成っぽい見え方をしているので加算モードにします

「シェーダー」
Blend One One

光って見えるようにEmissionの値も設定します

いい感じに加算されました

AoEはヘリの部分が光っていてあとはうっすら光っている
これを表現します

Alphaの値を設定することで重ね具合は表せそうです
Emissionの値も一緒に調整します

ヘリに近いところはAlphaが大きくなるようにシグモイド関数を利用します


加工したシグモイド関数

式を加工して半径の部分が立ち上がるようにします

「シェーダー」
       float expo = 1 / (1 + pow(2.7, -(_Gain) * (dist - _Range * 0.95)));
       o.Emission = _AoEEmission * expo;
       o.Alpha = expo * 0.5 + 0.3;




いい感じに表現できました。

ちなみにすこし重い。
処理改善の余地がありますね。

0 件のコメント:

コメントを投稿