読者です 読者をやめる 読者になる 読者になる

しゅみぷろ

プログラミングとか

歩いた場所の雪が凹むやつ作った

C# Shader Unity Graphics UnityTexturePaint

はじめに

こんな感じで、歩いた箇所の雪を凹ませるやつ作ってみました。

蛇足ですが、雪が積もって元の高さに戻るような処理も追加してあります。 短い動画でわかるよう積もるスピードめちゃ速くしてます。

見やすいように最初からかなり雪を厚くしていますが、DisplacementMapのおかげでInspectorから高さを調節できます。

歩いた後の雪がキレイに平で違和感がありますが、UnityTexturePaintで利用しているブラシ設定の問題で、ちゃんとブラシ設定割り当てるともうちょっとリアルになります。

f:id:es_program:20161029021907g:plain:w600

この処理ですが、Unite2016 Tokyo「いけにえと雪のセツナ」の講演内容を参考にさせて頂きました(雪面凹みと呼んでいらっしゃった気がする)。

当日講演見ていたのに今更の実装ですが、素晴らしい講演をありがとうございました。

雪世界でわちゃわちゃするゲームが作りたくなったので・・・。

実装について

大雑把に言うと

  1. 「どこを凹ませるのか」という情報を書き込んだテクスチャを用意
  2. 雪原のシェーディングの際に、1で作成したテクスチャを参照して頂点位置を弄る

の2ステップで実現できます。 以降は1と2で分けて解説します。

1. 「どこを凹ませるのか」という情報を書き込んだテクスチャを用意

「いけにえと雪のセツナ」では、歩いた場所をマークするため上からカメラで歩いた位置の情報をレンダリングしているらしい(?)です。 これによって、歩いた場所の情報を格納するテクスチャを作っています。

歩いた場所の情報を格納するテクスチャを雪原にマッピングする方法については触れられていなかった気がしますが、マッピングする何かしらの工夫がされているはずです。

UnityTexturePaintを利用する場合、直接当たり判定から当たった位置を取ってきて「どこを凹ませるのか」という情報をオブジェクトのテクスチャに書き込む事ができるので、雪原にマッピングする手法については考える必要ありません。

キャラクターが接地している雪原上の特定の場所に関して、ハイトマップペイントを施すだけで「どこを凹ませるのか」という情報を書き込んだテクスチャの用意が完了します。

UnityTexturePaintに関してはちょっと古いバージョンの情報になりますが以下の記事で。

esprog.hatenablog.com

2. 雪原のシェーディングの際に、1で作成したテクスチャを参照して頂点位置を弄る

ハイトマップにペイントできればこっちのものです。

雪原のシェーダーでVTFかDisplacementMappingを適用してやれば高さが変わります。 要するに、以前紹介した記事の応用です。

esprog.hatenablog.com

雪原はUnityデフォルトのPlaneを使っているのですが、Scale弄ってかなり広大な雪原マップを作るのならTessellationが必要になります。 ある程度細かいメッシュが用意できるのであればVTFで構わないと思います。

実は、メッシュはそんなに細かくなくても、ハイトマップから法線を取るアルゴリズムと法線を考慮したシェーディング処理さえしっかり書いてやれば割りといい感じに見えます。

色々やってみた感じ、雪原のメッシュを構成する三角形のそれぞれの辺の長さが動いているキャラクターの幅と同様くらいで、視点が雪面に近すぎなければまぁまぁ見れるレベルでした。

ハイトマップから法線を取るアルゴリズムは以下で解説しています。

esprog.hatenablog.com

最後に

ゲーム内のオブジェクトの描画で主要となる要素はメッシュ(頂点の集合)とテクスチャです。 ゲーム実行中にこれらを変更すると色々やれることも広がって、個人制作のゲームでも工夫次第では面白い表現が簡単にできるようになります。

頂点変形は(ちょっとした制約はあるものの)シェーダーで行えますし、あとはゲーム実行中にテクスチャに書き込めればシェーダーで出来る表現が増えます。

ちなみに、雪がもとの高さに戻っていく処理ですが、これはハイトマップペイント後のテクスチャを元のテクスチャに徐々に戻していく処理を追加しただけです。 ペイント後のテクスチャを次第にペイント前のテクスチャに戻す処理は結構面白い表現ができそうで、色々と使いどころを考えています。

f:id:es_program:20161027001205g:plain:w600

雪面の厚みを戻す以外にも、例えばステージの透明な部分を一瞬だけ見えるようなエフェクトを作ったり。

ゲームでよくある透明床的なやつの「実は歩ける場所」をうまーく表現できそうです。