【Unity】ShaderGraphで使用できる半透明オブジェクト含む背景テクスチャ_CameraTransparentTextureを作成、表示できるパスを追加する

はじめに

前回

bravememo.hatenablog.com

前回は_CameraOpaqueTextureに半透明オブジェクトを表示して背景を歪ませましたが、それだと既存の_CameraOpaqueTextureが使用できなくなります。

なので今回はURPでShaderGraphで使用できる背景テクスチャCameraTransparentTexture(半透明オブジェクト含む)を表示できるパスを追加して、CameraOpaqueTexture(不透明のみ)と_CameraTransparentTexture(不透明と半透明)で使い分けできるようにしていきます

環境は Unity 2020.3.25f1

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

前準備

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

シェーダーは前回とほぼおなじです

テクスチャの設定だけ違います。_CameraTransparentTextureに変更してあります

やり方

1.描画パスの追加

下記スクリプトを追加します

面倒なので解像度の変更は実装してません

using System;

namespace UnityEngine.Rendering.Universal.Internal
{
    public class CopyTransparentPass : ScriptableRenderPass
    {
        private RenderTargetIdentifier source { get; set; }
        private RenderTargetHandle destination { get; set; }
        const string m_ProfilerTag = "CopyColorTransparentPass";//FrameDebuggerで表示される名前

        public CopyTransparentPass(RenderPassEvent evt)
        {
            renderPassEvent = evt;
        }

        public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination)
        {
            this.source = source;
            this.destination = destination;
        }

        public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescripor)
        {
            RenderTextureDescriptor descriptor = cameraTextureDescripor;
            descriptor.msaaSamples = 1;
            descriptor.depthBufferBits = 0;
            //解像度を下げたいなら下記コメントを有効にしてください
            //descriptor.width /= 2;
            //descriptor.height /= 2;
            cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point);
        }
        //描画処理
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);
            RenderTargetIdentifier opaqueColorRT = destination.Identifier();

            Blit(cmd, source, opaqueColorRT);
            Blit(cmd, opaqueColorRT, source);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        //解放処理
        public override void FrameCleanup(CommandBuffer cmd)
        {
            if (cmd == null)
                throw new ArgumentNullException("cmd");

            if (destination != RenderTargetHandle.CameraTarget)
            {
                cmd.ReleaseTemporaryRT(destination.id);
                destination = RenderTargetHandle.CameraTarget;
            }
        }
    }
}
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace UnityEngine.Rendering.Universal.Internal
{
    public class TransparentRendererFeature : ScriptableRendererFeature
    {
        private CopyTransparentPass copyTransparentPass = null;//パス

        private RenderTargetHandle m_CameraColorAttachment;//コピー元テクスチャ
        private RenderTargetHandle m_CamerTransparentTexture; //コピー先テクスチャ

        [SerializeField]
         public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents;//レンダリングタイミング
        

        public override void Create()
        {
            copyTransparentPass = new CopyTransparentPass(renderPassEvent);
            //コピー元とコピー先のテクスチャ定義
            m_CameraColorAttachment.Init("_CameraColorTexture"); //コピー元 _CameraColorTextureにすることでレンダリングされてきた物が設定される
//_CameraColorTextureはUnityのバージョンによって名前が異なる可能性がある
            m_CamerTransparentTexture.Init("_CameraTransparentTexture"); //コピー先 shadergraphに設定するテクスチャ名はここで設定 名前は適当でいい
        }

        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            copyTransparentPass.Setup(m_CameraColorAttachment.Identifier(), m_CamerTransparentTexture);
            renderer.EnqueuePass(copyTransparentPass);
        }
    }
}

スクリプトを作成したらForwardRenderer.assetAdd Render Featureを押してTransparentRendererFeatureを追加します

これでパス追加完了です。これによりShaderGraphで_CameraTransparentTextureが使用できるようになります。

_CameraTransparentTextureの描画タイミングはRenderPassEventで指定してます

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

前回の記事とまったく同じなので解説を省略します。

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

完成

CameraOpaqueTextureと**CameraOpaqueTexture**を使用したものを両方配置してみました。

左が_CameraOpaqueTextureを使用したもので、右は_CameraTransparentTextureを使用したものになります。

終わりに

描画パスを追加したことでCameraOpaqueTextureとCameraOpaqueTextureの両方が使えるようになり便利になりました

表示がおかしくなる場合は、レイヤーの設定やEvent(描画順)が問題ないか確認してください

URP14版 bravememo.hatenablog.com