ShaderTips

シェーダーTips

主にUnityシェーダーについての記事を書いています。

SetTargetBuffers、Graphics.Blit、Graphics.SetRenderTargetでレンダーターゲットを切り替える

レンダーターゲットの切り替えを行うには以下のメソッドを使用します。

camera.SetTargetBuffers

docs.unity3d.com

1 つまたは複数のRenderTextureのバッファを選択されたカメラのレンダーに設定します。

var rt = new RenderTexture(300, 200, 24, RenderTextureFormat.ARGB32);
_camera.SetTargetBuffers (rt.colorBuffer, rt.depthBuffer);

カラーバッファ、深度バッファそれぞれ別のテクスチャにレンダリングしたいときや、複数のテクスチャをターゲットにしたいときはこのメソッドを使います。

Graphics.Blit

docs.unity3d.com TextureをターゲットのRenderTextureにコピーします。

Graphics.Blit(Texture source, RenderTexture dest, Material  mat);

この場合テクスチャsourceをRenderTextureのdstにコピーします。 マテリアルが指定されていた場合、マテリアルのシェーダーが使用されます。

Graphics.Blit(Texture source, null,  Material  mat);

destにnullを代入することで、sourceを画面に直接描画することができます。

Graphics.Blit(null, _renderTextureDst, _material);

sourceにnullを代入することで、画面の表示をレンダーテクスチャにBlitすることができます。

Graphics.SetRenderTarget

docs.unity3d.com

Graphics.SetRenderTarget(destRT.colorBuffer, sourceRT.depthBuffer);

カラーバッファ、深度バッファをレンダーターゲットに指定

Graphics.SetRenderTarget(RenderTexture rt);

RenderTextureをレンダーターゲットに指定。 RenderTexture.active = rtと中身は同じです。


実際に上記のメソッドを使用してスカイボックスの色を反転させます。 f:id:Ny_Program:20210522192022p:plain

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChangeRenderTarget : MonoBehaviour
{
    RenderTexture rt;
    [SerializeField]
    private Material mat;
    void Start()
    {
        var format = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) ? RenderTextureFormat.Default : RenderTextureFormat.ARGBHalf;
        // 画面サイズのレンダーテクスチャを作成
        rt = new RenderTexture(Screen.width, Screen.height, 24, format);
        rt.Create();

        // RenderTextureのバッファーをカメラに設定
        GetComponent<Camera>().SetTargetBuffers(rt.colorBuffer, rt.depthBuffer);
    }

    /// <summary>
    /// ここまでにRenderTextureにカメラの描画結果が入っている
    /// </summary>
    void OnPostRender()
    {
        // 色を反転させるマテリアルを設定してRenderTextureの結果を画面に描画する
        Graphics.Blit(rt, null ,mat);
    }
}

一応シェーダーも貼っておきます。

Shader "Hidden/InversionColor"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return 1.0 - col;
            }
            ENDCG
        }
    }
}

次回はCommandBufferについてやります。