草シェーダと水シェーダ [ゲーム開発ログ 2020-10-05]

2020-10-05

草を揺らす

  • 頂点シェーダで草を揺らすやつを実装中
  • ジオメトリシェーダでやるような物量のある草はやるつもりは無いが、 ゲームの中の植物オブジェクトがちょっと揺れてるくらいの味付けとして使いたい

  • 最近はこれを実装するため、「どんな揺れが気持ちよく見えるか」「世のゲームの草はどのように揺れているか」 といったことばかり気にしていた
    • 外に出たときも道端の草や街路樹の葉の揺ればかり見ていた
  • 最近リリースされた 原神 の草とかは物量もあるしキャラに反応して倒れたりするし揺れ方も自然ですごいなーと思った
    • まあ結構スペック要求するゲームではあるがそれにしても

水に浮かべる

  • 水シェーダも自前で実装中
  • 水シェーダは URP に対応しているものもアセットストアに見受けられるが、勉強も兼ねて自前で書いてみる

水面は半透明パスで描画。水との境界付近に色をつけるのは、デプスバッファを使う。 URP ではカメラの Depth Texture 設定を On にした上でシェーダで以下のように宣言するとデプステクスチャがとれるようになる:

TEXTURE2D(_CameraDepthTexture);  SAMPLER(sampler_CameraDepthTexture);

で、こんな感じの処理で描画位置からのデプス(水面からすでに描画されたフラグメントまでの距離)がわかるので、

float depth = LinearEyeDepth(
    _CameraDepthTexture.Sample(sampler_CameraDepthTexture, input.screenPos.xy / input.screenPos.w),
    _ZBufferParams
).r - input.screenPos.w;

それを利用して色を処理してやる。

水の向こうがうねうね歪んでいるような屈折表現は、URP では Opaque Texture を使う。 これは URP 以前の Built-in RP では GrabPass というパスで書いていたやつと同等。

不透明パスで描画された内容をテクスチャとして取得できるので、 その uv を適当にずらす感じで使ってやればよい。

最終的な実装については次回。