虫メガネやスコープみたいな表現をShaderでやる!【Unity】

2021年11月6日

ShaderGraphを使って虫メガネやFPSのスコープなどの表現を簡単に作って見ましょう。一部スクリプトも入りますが簡単に作ることが出来ますよ。

ズームシェーダーを作って虫メガネやスコープの表現を行う

今回はズームシェーダーというものを作り、それを利用しながら演出の完成を目指します。シェーダーはShaderGraphを利用しますので、プロジェクトにUniversal Render Pipelineの適応を行っておいてください。

Universal RP側の設定

今回のシェーダーではUniversal RP側の設定を少し変えておく必要があります。設定中のUniversal Render Pipeline Assetの[Opaque Texture]のチェックを下記のとおりにしてください。

こちらの設定を有効にすることで、カメラの不透明オブジェクト(Opaque) の描画結果が _CameraOpaqueTexture に書き込まれるようになります。

ShaderGraphでシェーダーを作る

シェーダーグラフを利用して、ZoomShaderを作成したいと思います。

プロジェクトビューで右クリックメニューから「Create>Shader>Universal Render Pipeline>Unlit Shader Graph」を選択してください。すると新規にファイルが作られますのでファイル名を「ZoomShader」とします。(もちろんなんでも構いませんよ)。作られたZoomShaderをダブルクリックしてShaderGraphEditorを立ち上げましょう。

ShaderGraphの編集

このシェーダーにとって重要なことは、オブジェクトの後ろの色を取得できるかどうかという点です。グラフの完成図はこちらですが、いくつかGraph Inspectorの設定に注意をしてください

FragmentのGraph Settingsは次のように設定してください。SurfaceをTransparentに変更しないとうまく透けて表示されません。

必要になるノードと変数は以下

必要なノード接続備考
Scene ColorOut(3) - Fragmen[BaseColor(3)]後ろが透けます
Tiling And OffsetOut(2) – Scene Color[UV(4)]拡大縮小が出来る
Screen PositionOut(4) – Tiling And Offset[UV(2)]見え方をまっすぐに出来る
One MinusOut(1) – Tiling And Offset[Tiling(2)]反転してたほうが使いやすい
MultiplyOut(2) – Tiling And Offset(2)シェーダーの中央合わせ
変数接続設定
float
ZoomAmount
One Minus[In(2)]
Multiply A(2)
Reference:_ZoomAmount
Mode : Slider
Default 0
Min/Max : 0 / 1
Vector2
ObjectScreenPos
Multiply B(2)Reference: _ObjectScreenPos
Default (0,0)
Precision Inhertit
Exposed true
Override・・・:false

調整用のスクリプトを追加

シェーダーだけではズーム時にずれが発生してしまうため、補正するためのスクリプトが必要になります。とりあえず下記スクリプトを用意してください。

using UnityEngine;
public class ZoomShaderScreenPos : MonoBehaviour
{
	[SerializeField]
	private Material mat;
	private void Update()
	{
		Vector2 screenPixels = Camera.main.WorldToScreenPoint(transform.position);
		screenPixels = new Vector2(screenPixels.x / Screen.width, screenPixels.y / Screen.height);
		mat.SetVector("_ObjectScreenPos", screenPixels);
	}
}

実際に使ってみる

上の項目にあるシェーダーとスクリプトが準備出来たら実際に使ってみましょう。

シーン内のオブジェクトなどの位置関係、アセット作成

わかりやすい画像で申し訳ないんですが、下記画像のような位置関係にしてください。

Cubeなど画面に写したいものとカメラの間にはさまるようにSphere(ズームサイト)を配置してください。この状態ではズームサイトが邪魔になっていてOKです。

ZoomShader用のマテリアルZoomMaterial作成

ズームサイトに設定するマテリアルを作成します。

  • プロジェクトビューでCreate>Materialを作成
  • 作成したマテリアルの名前はZoomMaterialとします(自由だけど以下説明のため名前を定義します)
  • ZoomMaterialのShaderをShaderGraphs/ZoomShaderに変更

コンポーネントなんかのセットアップ

作るものは作ったので、あとはどんどんセットアップして行きましょう。

ズームサイト

もとはSphereになっている今回の主役。

  • MeshRendererのマテリアルをZoomMaterialに変更
  • AddComponentでZoomShaderScreenPosを追加
  • インスペクター:ZoomShaderScreenPosのmatにZoomMaterialをセット
  • MeshColliderは不要なのでチェックボックスを外すかRemoveComponent

他にも設定あると思ったら一つだけだった。

動かしてみる

以上の設定が出来たら、実際に動かしてみましょう。Unityを再生して、ズームサイトのマテリアルにあるZoomAmountを変更してズームサイトがズームアップするのを確認してください。

またその状態で位置を変更するとちゃんとズームされる位置が変わるのを確認してください。

注意点

シーンビューでもズームっぽく出来るのですが、再生後のゲームビューで反映される方が本番なので、シーンビューでしっくり来なくても心配しないでください。

あとは、君自信の目で確かめてくれ!