BLOGワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。アルゴリズムこんにちは、エンジニアの成田です。今回もUnityのシェーダで遊んでみます。今回はタイトルの通り「VRっぽい」シェーダを作ってみました。VRのシェーダと言っても最近流行りのヘッドマウントディスプレイOculus等の視差シェーダみたいなものではなく、あくまで「演出上のVR」、よくアクションゲームなんかに登場する空間のソナーみたいな効果を作ってみました。説明が難しいですけど、なんというか、SF映画のトロンみたいなグリッドの表現です。注意点として今回の実装はあくまで私流のやり方で試行錯誤したものですので、もっと美しく処理も軽い方法があるかもしれませんが、ご了承ください。いうか良い方法教えて下さい......また、今回作成するシェーダはピクセルシェーダの負荷が結構高いと思われますので、実用は厳しいかもしれません。1.方針とりあえずシーン内で多様なサイズのオブジェクト同士での整合性を取るために、グリッドのテクスチャを貼ることは考えず(グリッドがオブジェクト同士を跨いでも問題無いようにUVを指定していくのは非現実的)、ワールド座標とカメラ座標を使ってピクセルシェーダでグリッドの線を引くことにします。2.実装まず、空間座標に対して矩形波とノコギリ波みたいな波形を出力する、次のような関数を作成しました。periodは波の周期、widthは「波の1になる部分」の幅です。これをグラフで表すとこんな感じになります。数学関数を一杯かませた無理やり感...。これを使って空間にグリッド線を引きます。periodは波の周期、fadeは減衰の幅です。カメラ座標を減算しているので原点はカメラの位置になります。このノコギリ波は先ほどの矩形波と積算してグリッドのグラデーションに使ったり、ソナー波の演出に使います。このようなシーンを用意してみました。このシーンに先ほどの矩形波を適用した結果がこれ。ノコギリ波を適用した結果がこれ。うーん、ノコギリ波の方の結果は想定通りですが、矩形波の方はオブジェクトに関してはグリッドが引かれていますが、床や壁のPlaneが真っ白になってしまっています。これには理由があって、y=0の平面など罫線が引かれる軸に平行な面を持つポリゴンは、ポリゴン全体が罫線上に存在する時にすべてのピクセル出力が1となり真っ白になってしまう可能性があります。そこでちょっとした小細工を行います。ポリゴンの法線ベクトルをワールド座標系に変換して、これがxyzいずれかの軸に平行ならその軸方向の罫線をそのポリゴンでは描かなくします。法線がワールド+y方向のポリゴンがあれば、xz軸の罫線だけ引くという感じです。factorX/Y/Zは描画の係数になります。法線ベクトルが各軸に対して平行だと0、直交していると1に近くなります。この実行結果はこうなります。d.ノコギリ波の改造ノコギリ波の出力は正しかったのですが、ソナー波なのでアニメーションしてほしい。あと遠くなるにつれて全体として減衰してほしい。4を減算しているのでグラフで言えば各軸の-方向へアニメーションすることになります。最終結果を1+distFromCamで除算することで減衰っぽくしています。実行結果はこうなります。ここまで来たら必要な要素はほぼ完成しています。あとは下のように組み合わせてお目当ての演出の見た目を作ります。細い線だけでグリッドを構成しても良いんですが、今回は見た目を良くするために矩形波を2つ使って太い線(A)と細い線(B)を加算してグリッド(C)を作ります。上で作成したグリッド(C)にフェード幅を大きめにしたノコギリ波(D)を積算します。これでグリッドにグラデーションがかかりソナーっぽい見た目になります(E)。上のグラデーション付きグリッド(E)にソナー波の衝撃面の演出を乗せます。フェード幅を小さくしたノコギリ波(F)を加算します(G)。これでソナー波は完成です。あとは掛け&足しあわせの係数(強さ)を微調整します。以下が、今回作ったサーフェイスシェーダの全体です。法線ベクトルの処理の部分はピクセルシェーダでやるよりバーテックスシェーダでやるべきなんでしょうけど、とりあえず、ということで......。最後に、味付けとしてポストエフェクトをかけましょう。SF映画と言えば光の効果、光の効果と言えばSF映画(多分)。HDRとブルーム効果を使って眩しい感じの画面にします。これに備えて実は上のシェーダでは最終出力が[0.0,1.0]よりも広い範囲を返しています。カメラのHDRをオンにして、Bloomのコンポーネントを追加します。パラメータを次のように設定してみました。