【Unity】_CameraOpaqueTexture(SceneColor)で半透明を描画できるようにして半透明オブジェクトを含めた背景を歪ませる

はじめに

今回はURPで_CameraOpaqueTexture(SceneColor)で半透明を描画出来るようにしていきたいと思います

環境は Unity 2020.3.25f1(2019.4でも出来ることは確認しました)

Universal Render Pipeline(テンプレートのプロジェクトです)

前準備

CameraOpaqueTextureにチェックを入れてCameraOpaqueTextureを使用できる状態にします

追記 2022.2では_CameraOpaqueTexture項目はなくなっています。代わりにScene Color Node を使用してシェーダーを作成してください

_CameraOpaqueTextureが半透明を描画できるのを確認できるように歪みシェーダーを用意します

この記事の内容が知りたい人はおそらく歪みシェーダーの作成方法は知っているはずなので詳しくは解説しません。

参考

effect-lab.hatenablog.com

zenn.dev

マテリアルはこんな感じ

適当に板を配置しました。

現時点だと板の後ろにある半透明のパーティクルが描画されておらず歪んでないのがわかります

対応方針

_CameraOpaqueTexture(SceneColor)の描画タイミングは下記にようになっています

これを下記のようにします

重要な点としては歪みオブジェクトの描画は必ず_CameraOpaqueTextureの描画後でないといけないところです。

これを守らないと下記のようなおかしな画像になります。

やり方

1._CameraOpaqueTextureの描画順を変更

元々Unityに組み込まれてるレンダリング順を変更するためにURPを拡張できる状態にします

Library\PackageCache内にあるcom.unity.render-pipelines.universal@10.7.0(バージョンをUnityにバージョンによって違う)をPackagesにコピーします

参考

qiita.com

someiyoshino.info

そうしたらForwardRender.csを開きます(2021.2だとUniversalRenderer.csになってます)

  m_CopyColorPass = new CopyColorPass(RenderPassEvent.AfterRenderingSkybox, m_SamplingMaterial, m_BlitMaterial);

上記処理を以下のように変更します

  m_CopyColorPass = new CopyColorPass(RenderPassEvent.AfterRenderingTransparents, m_SamplingMaterial, m_BlitMaterial);

CoppyColorPassの引数でAfterRenderingTransparentsを渡すことで_CameraOpaqueTextureが半透明オブジェクト描画後に描画するようになります

ここまで変更加えるとSceneは下記のようになります

歪みオブジェクト(半透明オブジェクト)描画後に_CameraOpaqueTextureを描画がしてることによって見た目がおかしくなります

2.歪みオブジェクトの描画順を変更

やり方は下記記事とほぼ同じになります

bravememo.hatenablog.com

最初に歪みオブジェクト用のレイヤーを作成、設定をします

次にSetttingsフォルダ内にあるForwardRender.assetを下記のように編集します

これにより歪みオブジェクト用のレイヤーは半透明オブジェクト描画のタイミングで描画されなくなります

最後にForwardRender.asset内にあるAdd Render Featureを押してRender Objectsを追加し下記のようにパラメータを設定します

Eventで描画タイミングを指定しており、BreforeRenderingPostProcessingにすることで_CameraOpaqueTextureの描画後(AfterRenderingTransparents)に描画することが出来ます

完成

半透明オブジェクトであるパーティクルが_CameraOpaqueTextureに描画されてることによってパーティクルが歪むようになりました

FrameDubuggerでも確認してみます

DrawTransparentObjects(半透明オブジェクトの描画) → CopyColor(_CameraOpaqueTextureの描画) → NewRenderObjects(歪みオブジェクト用のレイヤーが設定されいるオブジェクトの描画)の描画がされていることがわかります。

おわりに

_CameraOpaqueTextureに必ず半透明オブジェクトの描画されるようにできたので、次は半透明オブジェクトの描画がされるものとされないもので使い分けできるようにしていきたい

次回

bravememo.hatenablog.com