Unity CommandBuffer MTR to render custom RenderTexture

aims:

Rendering the delay, sometimes we have to first model Diffuse, Normal, Depth, Roughness and other data from the first wash to RenderTexture defined (CPU, a map stored in the form of several to Disk), and then the light is delayed behind the peer computing.

Ideas:

  • The method
    can be directly rendered by Camera, as long as the customized RT target is set to the camera (MRT Camera be used in SetTargetBuffers (RenderBuffer [] colorBuffer, RenderBuffer depthBuffer) method sets the render target);
  • Method Two
    that the use of CommandBuffer custom rendering instructions shading, this can be a model for rendering maps, get Render object model, calling CommandBuffer of DrawRenderer (render, material) method and execute CommandBufferGPU instruction at the right time.

CommandBuffer way to achieve

Be customized to initialize and several RT for buffering the rendered result, a new custom setting CommandBuffer render target and drawing instruction, and to execute at the right time CommandBuffer:

    public Transform targetObj; // 要渲染的模型

    RenderTexture[] rtGBuffers = new RenderTexture[3]; // 自定义RT
    RenderTexture depthBuffer = null; // 深度RT
    public Material GBufferMaterial; // 渲染MRT的材质,自定义shader
    Renderer targetRender; // 模型的Render对象

    void Start()
    	{
        targetRender = targetObj.GetComponent<MeshRenderer>();
        CommandBuffer cmd = new CommandBuffer();
        cmd.name = "TestGBufferCMD";
        RenderTargetIdentifier[] rtGBuffersID = new RenderTargetIdentifier[rtGBuffers.Length];
        for (int i = 0; i < rtGBuffers.Length; ++i)
        {
            rtGBuffers[i] = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);
            rtGBuffersID[i] = rtGBuffers[i];
        }
        depthBuffer = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);

        cmd.SetRenderTarget(rtGBuffersID, depthBuffer); // 设置渲染目标
        cmd.ClearRenderTarget(true, true, Color.clear, 1);
        cmd.DrawRenderer(targetRender, GBufferMaterial); // 绘制指令
        
        // 这里可以在相机的渲染事件中自动执行CommandBuffer
        Camera.main.AddCommandBuffer(CameraEvent.BeforeForwardOpaque,cmd);
        }

Further CommandBuffer may be executed at an appropriate position of the manual:
Graphics.ExecuteCommandBuffer(cmd);

Custom MRT shader example:

Shader "Unlit/GBuffer"
{
	Properties
	{
		_MainTex ("MainTex", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100
        Cull Back

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

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

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

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normal = float4(v.normal,0);
				return o;
			}
			
			void frag (v2f i,
            out half4 GRT0:SV_Target0,
            out half4 GRT1:SV_Target1,
            out half4 GRT2:SV_Target2,
            out float GRTDepth:SV_Depth
            )
			{                
				// sample the texture
				float4 col = tex2D(_MainTex, i.uv);
                GRT0 = col;
                GRT1 = i.normal;
                GRT2 = float4(0,0,1,0);
                GRTDepth = 0.5;
			}
			ENDCG
		}
	}
}

View Results

Run Unity, Open Frame Debuger cut one, to find our CommandBuffer that instruction, then we can see there are three RT, RT choose a different view map results. RT has been the custom in memory, you can save the picture to the local for later use.

Here Insert Picture Description

Published 109 original articles · won praise 403 · views 880 000 +

Guess you like

Origin blog.csdn.net/cordova/article/details/100746757