geometry shaderで草原を作る

はじめに

geometry shaderで草原を作ったのでメモします。

  • Unityのバージョン:2018.3.0b8

ソースコード

ソースコードは次のリポジトリに置いてあります。

動画

次の動画は作成した草原の動画です。

草を生やす

geometry shaderでメッシュの頂点を受け取って、 その頂点の位置に草のメッシュを生成しています。

生成する草のメッシュは次のような平面を十字に交差させた形です。

このメッシュに次の草のテクスチャを貼っています。

頂点IDをSV_VertexIDセマンティクスで受け取って、 その値をもとにランダムで4種類の草を切り替えています。

ランダムの関数には次のものを使いました。

2次元の値を渡す必要があるようなので.xxとして渡しています。

草を生やすもととなるメッシュにはBlenderて適当に分割したメッシュを読み込みました。

66173頂点だそうです。

シェーディング

フラグメントシェーダでDeferredのGBufferを書き出しています。 次のページを参考にDeferredのGBufferの書き出しを実装しました。

草を揺らす

草を揺らすのにはパーリンノイズを使っています。 パーリンノイズには次のコードを使わせてもらいました。

x方向の揺れとy方向の揺れでそれぞれ別の速度を与えてノイズをスクロールさせています。

草を刈り取る

草を生やしたらやっぱり刈り取りたくなります。

草の刈り取られた割合をメッシュの頂点カラーのrに格納します。 頂点カラーのrの値をもとに背丈を短くしてUVも適切にずらして描画します。

スクリプトで草1本に付き1本のRayを飛ばして当たり判定を行い、 ヒットしたらrに小さな値を書き込むようにしました。

私の環境では6万本の当たり判定をUpdateで回すと60fpsを切るようになってしまいました。 真面目に草原を作りたいならば何かしらの工夫は必要そうです。

おわりに

geometry shaderをはじめて触ってみましたが なかなか面白いです。

今回作った草原は、草に当たり判定とかをつけないのであれば シェーダ側だけで完結できるのが楽でいいですね。 適当にメッシュを与えるとそこから草が生えるのは面白いです。