Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Render GBuffer to RenderTexture

Discussion in 'General Graphics' started by cowtrix, Oct 6, 2017.

  1. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    I'm trying to record some GBuffer information from a camera when it's rendered, and save it into a RenderTexture format. Similar to the debug views in the SceneView, I'd like to capture the Albdeo, Smoothness, Specular, and Normals from the GBuffer for later use. I'm pretty sure this is possible with CommandBuffers but I'm not sure how to use them. I've attached my little attempt at it, but I just get a bunch of black rendertextures from it.

    I'm trying to cannibalise a bit of this project: https://github.com/unity3d-jp/FrameCapturer

    The shader field in the class below is a 1:1 copy of the shader in the above repo.

    Yo @i-saint - I think you wrote the above. Any thoughts?

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3.  
    4. public class TerrainBasemap : MonoBehaviour
    5. {
    6.     public int Resolution = 1024;
    7.     public Shader CaptureShader;
    8.  
    9.     public RenderTexture[] Textures = new RenderTexture[8];
    10.  
    11.     [ContextMenu("Recalculate")]
    12.     public void Recalculate()
    13.     {
    14.         for (int i = 0; i < Textures.Length; i++)
    15.         {
    16.             var renderTexture = Textures[i];
    17.             if (renderTexture != null)
    18.             {
    19.                 DestroyImmediate(renderTexture);
    20.             }
    21.             renderTexture = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBHalf);
    22.             renderTexture.filterMode = FilterMode.Point;
    23.             renderTexture.Create();
    24.             Textures[i] = renderTexture;
    25.         }
    26.  
    27.         var tmpOut = RenderTexture.GetTemporary(Resolution, Resolution, 0, RenderTextureFormat.ARGBHalf);
    28.         var m_matCopy = new Material(CaptureShader);
    29.         var m_quad = CreateFullscreenQuad();
    30.  
    31.         var cam = SetupCamera();
    32.         cam.targetTexture = tmpOut;
    33.  
    34.         var m_cbClearGB = new CommandBuffer();
    35.         m_cbClearGB.name = "GBufferRecorder: Cleanup GBuffer";
    36.         if (cam.allowHDR)
    37.         {
    38.             m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
    39.         }
    40.         else
    41.         {
    42.             m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.GBuffer3);
    43.         }
    44.         m_cbClearGB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 3);
    45.         m_matCopy.SetColor("_ClearColor", cam.backgroundColor);
    46.         cam.AddCommandBuffer(CameraEvent.BeforeGBuffer, m_cbClearGB);
    47.  
    48.         var cBuffer = new CommandBuffer();
    49.         cBuffer.SetRenderTarget(new RenderTargetIdentifier[]
    50.         {
    51.             Textures[0], Textures[1], Textures[2], Textures[3], Textures[4], Textures[5], Textures[6]
    52.         }, Textures[0]);
    53.         cBuffer.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 0);
    54.         cam.AddCommandBuffer(CameraEvent.BeforeLighting, cBuffer);
    55.  
    56.         cam.Render();
    57.         cam.targetTexture = null;
    58.  
    59.         RenderTexture.ReleaseTemporary(tmpOut);
    60.     }
    61.  
    62.     private void SetupLighting()
    63.     {
    64.         RenderSettings.ambientLight = Color.white;
    65.         RenderSettings.ambientMode = AmbientMode.Flat;
    66.     }
    67.  
    68.     private Camera SetupCamera()
    69.     {
    70.         var go = new GameObject();
    71.         var cam = go.AddComponent<Camera>();
    72.  
    73.         var terrain = GetComponent<Terrain>();
    74.         var tSize = terrain.terrainData.size;
    75.  
    76.         cam.orthographic = true;
    77.         cam.orthographicSize = tSize.x/2;
    78.         cam.nearClipPlane = 1;
    79.         cam.farClipPlane = tSize.y*1.2f;
    80.  
    81.         cam.aspect = 1;
    82.         cam.pixelRect = new Rect(0, 0, Resolution, Resolution);
    83.    
    84.         cam.transform.position = terrain.GetPosition() + new Vector3(tSize.x/2, tSize.y, tSize.z/2);
    85.         cam.transform.rotation = Quaternion.LookRotation(Vector3.down);
    86.  
    87.         return cam;
    88.     }
    89.  
    90.     public static Mesh CreateFullscreenQuad()
    91.     {
    92.         var r = new Mesh();
    93.         r.vertices = new Vector3[4] {
    94.                     new Vector3( 1.0f, 1.0f, 0.0f),
    95.                     new Vector3(-1.0f, 1.0f, 0.0f),
    96.                     new Vector3(-1.0f,-1.0f, 0.0f),
    97.                     new Vector3( 1.0f,-1.0f, 0.0f),
    98.                 };
    99.         r.triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
    100.         r.UploadMeshData(true);
    101.         return r;
    102.     }
    103. }
     
    Last edited: Oct 6, 2017
  2. ElementMo

    ElementMo

    Joined:
    Jul 12, 2018
    Posts:
    4
    Orthographic camera does not support GBuffer, which was determined by the nature of GBuffer itself.