DENXブログ

同志社大学 電気情報研究会(DENX)の活動や日常風景などを紹介します。

Unityでカップシャッフルのゲーム作り

こんにちは今出川のくるーておです。突然ですが、最近カップシャッフルとfpsを掛け合わせたゲームを思い付いたのでモデリングの合間にunity でちょこちょこ作っています。その途中、コップの中身を見ることのできる強いアイテムを思い付いたので実装してみました。(動画後半参照)


CupshuffleWip
(まだ途中です。コップの中身が見えてしまう虫メガネだけにご注目ください。)

今回はこの虫メガネを作るのに色々なサイトを参考にしたので、忘備録代わりにここで整理しておきます。主にunityのshaderに関する記事となります。

こちらがノーマルの状態です。 f:id:denx:20190628222623j:plain

①色を変える

f:id:denx:20190628234900j:plain 当たりボールがわかるように、コップと当たりボールそれぞれ緑と赤のリプレイスシェーダーで色をかえます。ここでの注意はボールのRenderQueueです。コップのなかに入っているボールを先にレンダリングするために、当たりボール、コップ、レンズの順に描画するように注意しましょう。(transparentで統一してます。)深度テストは背面も映すために全てalways にしてあります。

②ぼかす

f:id:denx:20190628235031j:plain レンズのぼかしをcommand bufferでRenderTextureを取得しつつ作り出します。(ぼかしのfragment処理は先人の知恵をお借りしました。)ただし、command buffer はAfterForwardAlphaのタイミングに挿入します。これは後に登場するステンシルバッファが破棄される前にイメージエフェクトをかけるためですが、正直カメライベント周りはまだよくわかってない部分が多いです...。

③範囲を制限する

f:id:denx:20190628235156j:plain レンズの範囲のみイメージエフェクトが描画できるよう、ここではレンズ代わりのPlaneがステンシル値をピクセルに埋め込み、残りのシェーダーをステンシルします。イメージエフェクトを写し出すカメラと、通常のカメラの2つを用意し、イメージエフェクトカメラにはPlaneの範囲のみ映し出します。そしてそれをメインカメラに重ねることによってレンズの外と内で描写を分けます。

  • shaderで2passかいてバッファ値の外と内を分けて書けばカメラをふやさなくてよいというご意見もあるかもしれませんが、場面に登場するオブジェクトはさまざまなshader 、テクスチャで描かれています。 それら一つ一つ二つ目のpass をかいたり、テクスチャを当てはめたりするのは面倒臭いのでカメラを増やすアプローチにしました。
④影

f:id:denx:20190629000301j:plain 最後は影です。実は昨年、unity のベイク回りに関する記事をかいたのですが、最後に「シャドウマップの自作をしてみたい」なんてことを書いていました。 denx.hatenablog.jp 1年後しにようやく実現できそうです。

そもそも、unlitシェーダーなのに影を落とせるのか?なんて疑問を持つかもしれませんが、方法は結構あります。(lightModeのマクロやデプスシャドウ方式の自作など) ここでは、原始的な投影デプスシャドウ方式を採用します。
まず、↓画像が光視点のレンダーテクスチャです。 f:id:denx:20190629000222j:plain 投影デプスシャドウ方式では、このレンダーテクスチャをシャドウマップとして扱います。簡単に説明すると光の視点からみたレンダーテクスチャを行列をかけてメインカメラからみた影のシルエットテクスチャに変換し、影を落としたい床のプレーンに張り付けるといった具合ですね。  

加えてレンダーテクスチャ自体をリプレイスシェーダーで分かりやすく色を変えてやります。二色のレンダーテクスチャにしてやればあとは色の値を参考に影の部分とそうでない部分で線形補完できて見た目的にも良いです。

①~④を合わせた結果がこちら。 f:id:denx:20190629000403j:plain 次はCommandBufferを使って何か作ってみたいですね。