こんにちは、Unityエンジニアのオオバです。
前回超基本編として Universal Render Pipeline(以下:URP) の拡張方法を紹介しました。
とても簡単にわかりやすく 紹介していますので、URP拡張に興味ある方はぜひ見てください。
導入としてちょうど良いと思います。
本記事と前回の違いは シェーダーを使っていること です。
不透明のオブジェクトだけにカラー乗算するというURPの描画拡張を作っていきます。
今回の本質はシェーダーを使ったURPの拡張のため、シェーダーの内容は超簡素です。
基本をおさえた上で難しいシェーダーを書いていきましょう。
👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!
FeatureとPassの用意
URPを拡張する上ではおなじみの手順です。
- HelloWorldShaderRendererFeature.cs
- HelloWorldShaderPass.cs
それぞれScriptableRendererFeature
とScriptableRenderPass
を継承して作成します。
URP ForwardRendererのRenderer Features
に追加します。
このあたり前回記事で丁寧に紹介していますので、そちらをご確認ください。
シェーダーの用意
💻ソースコード : HelloWorldShader.shaderの抜粋
fixed4 frag (v2f_img i) : SV_Target
{
return tex2D(_MainTex, i.uv) * _Color;
}
各ピクセルを_Color
プロパティを乗算するシンプルなシェーダーです。
シェーダーの全ソースはコチラです。
このシェーダーファイルをFeatureにセットします。
💻ソースコード : HelloWorldShaderRendererFeature.cs
[SerializeField] private Shader _shader;
Materialを生成してPassに渡す
FeatureとPassの関係を思い出しましょう。
Feature
はあくまでPassの生成器。
Pass
は描画処理担当です。
FeatureはPassにShaderをセットしたMaterialを渡します。
💻ソースコード : HelloWorldShaderRendererFeature.cs
public override void Create()
{
// ShaderからMaterialを生成
var material = CoreUtils.CreateEngineMaterial(_shader);
// PassにMaterialを渡す
_pass = new HelloWorldShaderPass(material);
}
シェーダーからMaterialを作る時は、CoreUtils.CreateEngineMaterialメソッド
が便利。再生終了時に自動でMaterialの破棄をしてくれます。
レンダーターゲットにシェーダーを適用
今回の肝、シェーダーの適用です。
- RenderTexture生成
- カメラ画像をRenderTextureにコピー
- RenderTextureをカメラ画像にコピー
2. カメラ画像をRenderTextureにコピー
のタイミングでシェーダーを適用します。
💻ソースコード : HelloWorldShaderPass.cs Executeメソッド内
// カメラ画像をRenderTextureにコピー
commandBuffer.Blit(_currentRenderTarget, RenderTargetTexId, _material);
CommandBuffer Blitメソッドの
第3引数にMaterialを渡すことでシェーダーは適用されます。
Blitメソッドの解説
- 第1引数 : 元の画像ID
- 第2引数 : 書き出し画像ID
- 第3引数 : 適用シェーダー
もっとわかりやすくした図はコチラ。
- 元の画像 : カメラ画像
- 書き出し画像 : RenderTexture(シェーダー適用済み)
Blitメソッドをまとめると、元画像をコピーしてシェーダーを適用。シェーダーを適用したデータを書き出し画像に書き込みます。
↑これだけ覚えておきましょう。
_MainTexで元画像をシェーダーから参照
Blitメソッド
の第1引数のカメラ画像はシェーダーからどのように参照すればよいでしょうか。
答え : シェーダー内で定義した、_MainTex
という変数に格納されます。
このあたりはUnityの仕様です。
@ref:https://docs.unity3d.com/ja/2021.1/ScriptReference/Rendering.CommandBuffer.Blit.html
今回実装した画像処理を振り返ります。該当するシェーダー処理はコチラ。
💻ソースコード : HelloWorldShader.shaderの抜粋
fixed4 frag (v2f_img i) : SV_Target
{
return tex2D(_MainTex, i.uv) * _Color;
}
_MainTex
(カメラ画像)の各ピクセルを_Color
で乗算しています。
カメラに映し出された画像に指定の色で塗られる処理になります。
処理した画像をカメラに戻す
RenderTextureをいくら加工してもカメラ画像に戻さなければ見た目は変わりません。
// RenderTextureにシェーダーを適用
commandBuffer.Blit(_currentRenderTarget, RenderTargetTexId, _material);
// シェーダー適用したRenderTextureをカメラ画像にコピー
commandBuffer.Blit(RenderTargetTexId, _currentRenderTarget);
再度Blitメソッド
が登場します。処理済み画像をカメラ画像にコピーしてモニタ上の見た目を更新します。
このように、シェーダーを適用したURP拡張ができました!
もう少し続けます。
シェーダーのパラメータを動的に更新する方法
URP拡張にシェーダーを適用できました。
このシェーダーのパラメータを動的に変えてみようと思います。
調整したいFeatureにColorパラメータをpublic変数として公開します。
public Color color;
するとインスペクタからカラーを変更できるようになります。
図にするとこんなイメージです。
このcolor
を毎フレーム更新することでリアルタイムに変更できます。
まとめ
シェーダーを使ったURPの拡張方法を紹介しました。
- Blitメソッドの第3引数にMaterialを渡す
- シェーダーの_MainTexにRenderTextureが渡ってくる
- _MainTexにBlitメソッドの元画像がセットされる
前回、今回記事を通して基本的なURPの拡張方法を理解できたかと思います。
おつかれさまでした。
次回から、より複雑な題材をテーマにURPの拡張をしていきたいと思います。
お楽しみに!
ソースコード全文はこちら
最後にサンプル全ソースを公開しておきます。
サンプルも内包されて分かりづらいですが、Assets/HelloWorldRendererFeatureSampleフォルダ
に今回のサンプルは入っています。
何か参考になれば幸いです。
GitHub - baobao/URP-HelloWorldRendererFeature
この記事が気に入ったらフォローしよう
「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
ぜひチャンネル登録をお願いします!
最後まで読んでいただきありがとうございました!
すばらしいURP拡張ライフをお過ごしください。
- Unity2021.16.f1
- URP v11.0.0