Search Unity

Custom Deferred Shading

Discussion in 'General Graphics' started by WGermany, Dec 25, 2014.

  1. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Hey everyone, I've been working on a custom deferred shading renderer inside of Unity similar to what Dolkar and Aieth have made here on the forums. I have been very unsuccessful though in terms of fixing a major flaw. I posted my issue in the scripting section but I think its better to post here as I assume most of that traffic has no idea of what I am proposing here.

    All of the buffers display correctly, the lighting works but it doesn't update past the first frame rendered to the screen. So when I press play it renders the first screen, and if I move an object or the camera nothing happens. I believe it has something to do with the Replacement shader funtions.

    TL;DR -> My issue is that the camera does not update what's being rendered.

    Code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class DeferredShading : MonoBehaviour
    4. {
    5.     Camera originalCamera;
    6.     Camera renderingCamera;
    7.     public static RenderTexture[] RTs;
    8.     public Shader GBufferShader;
    9.     public Shader DirectionalLightShader;
    10.     public Light MainLight;
    11.     [Range(0, 10)]
    12.     public float LightIntensity = 1.0f;
    13.     public Color LightColor = Color.white;
    14.     private RenderBuffer[] colorBuffers;
    15.     private RenderBuffer depthBuffer;
    16.     private Material DirectionalLightMaterial;
    17.     private Material GBufferMat;
    18.     void Awake()
    19.     {
    20.         originalCamera = camera;
    21.     }
    22.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    23.     {
    24.         if(!GBufferMat)
    25.         {
    26.             GBufferMat = new Material(GBufferShader);
    27.             GBufferMat.SetTexture("_MainTex", RTs[0]);
    28.             GBufferMat.SetTexture("_NormalTexture", RTs[1]);
    29.             GBufferMat.SetTexture("_DepthTexture", RTs[1]);
    30.             GBufferMat.SetTexture("_SpecColor", RTs[2]);
    31.             source = RTs[0];
    32.      
    33.             Graphics.Blit(RTs[0], destination, GBufferMat);
    34.             Graphics.Blit(RTs[1], destination, GBufferMat);
    35.             Graphics.Blit(RTs[2], destination, GBufferMat);
    36.      
    37.         }
    38.  
    39.         if(!DirectionalLightMaterial)
    40.         {
    41.             DirectionalLightMaterial = new Material(DirectionalLightShader);
    42.             DirectionalLighting(source, destination);
    43.         }
    44.     }
    45.     void OnEnable()
    46.     {
    47.         CreateCamera();
    48.     }
    49.     void CreateCamera()
    50.     {
    51.         ReformCameras();
    52.         CreateBuffers();
    53.     }
    54.     void OnPostRender()
    55.     {
    56.         renderingCamera.SetTargetBuffers(colorBuffers, depthBuffer);
    57.         renderingCamera.RenderWithShader(GBufferShader, "");
    58.     }
    59.     void OnGUI()
    60.     {
    61.         //GUI.DrawTexture(new Rect(0, 0, RTs[0].width, RTs[0].height), RTs[0], ScaleMode.StretchToFill, false);
    62.     }
    63.     public void DirectionalLighting (RenderTexture Input, RenderTexture Output)
    64.     {
    65.         DirectionalLightMaterial.SetFloat("_LightIntensity", LightIntensity);
    66.         DirectionalLightMaterial.SetColor("_LightColor", LightColor);
    67.         DirectionalLightMaterial.SetVector("_LightDirection", MainLight.transform.forward * 1.0f);
    68.         DirectionalLightMaterial.SetTexture("_MainTex", RTs[0]);
    69.         DirectionalLightMaterial.SetTexture("_NormalTexture", RTs[1]);
    70.         Graphics.Blit(Input, Output, DirectionalLightMaterial);
    71.     }
    72.     void ReformCameras()
    73.     {
    74.         renderingCamera = new GameObject("RenderingCamera").AddComponent<Camera>();
    75.  
    76.         renderingCamera.enabled = false;
    77.  
    78.         renderingCamera.transform.parent = transform;
    79.         renderingCamera.transform.localPosition = Vector3.zero;
    80.         renderingCamera.transform.localRotation = Quaternion.identity;
    81.  
    82.         originalCamera.renderingPath = RenderingPath.VertexLit;
    83.         originalCamera.cullingMask = 0;
    84.         originalCamera.clearFlags = CameraClearFlags.Depth;
    85.         originalCamera.backgroundColor = Color.black;
    86.  
    87.         renderingCamera.renderingPath = RenderingPath.VertexLit;
    88.         renderingCamera.clearFlags = CameraClearFlags.SolidColor;
    89.         renderingCamera.farClipPlane = originalCamera.farClipPlane;
    90.         renderingCamera.fieldOfView = originalCamera.fieldOfView;
    91.     }
    92.     void CreateBuffers ()
    93.     {
    94.         RTs = new RenderTexture[] {
    95.             RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default),
    96.             RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default),
    97.             RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default) };
    98.  
    99.         colorBuffers = new RenderBuffer[] { RTs[0].colorBuffer, RTs[1].colorBuffer, RTs[2].colorBuffer };
    100.         depthBuffer = RTs[1].depthBuffer;
    101.     }
    102.     void OnDisable()
    103.     {
    104.         Destroy(renderingCamera.gameObject);
    105.     }
    106. }
     
  2. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Hey there! I'm glad to see yet another unity graphics hacker :)

    Now, what debugging have you done so far? Have you checked that the OnPostRender and OnRenderImage functions are running? If so, are the draw calls actually getting processed? You can see that in the unity's profiler. If the draw call isn't there or if it takes suspiciously little time, something is wrong.

    I think I know what's going on there though.. look inside the OnRenderImage function.. both of these conditions are true only during the first frame / call. Also, the three blits don't make sense to me at all.
     
    JecoGames and WGermany like this.
  3. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78

    I've debugged the render textures, they all work as you can see here:
    http://i.imgur.com/zTXDe54.png

    The OnPostRender and OnRenderImage funtions are indeed running. It detects polygons and draw calls perfectly. I move the camera around towards a mesh and it updates the information in the profiler, as well as the stats window showing an increase in draw calls as well as more triangles when facing the object(s).

    And yes the three blits there aren't needed, you are right. I was experimenting with a lot of thing in the processed and forgot to remove them.

    Although what do you mean by the conditions are true only during the first frame?

    Thanks a lot for your help by the way!! I've been trying to fix this for quite sometime :D
     
  4. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    DOLKAR YOU GENIUS. I fixed the issue! Thank you so much!!!!!! :D
     
  5. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Ehh, you're welcome I guess :) Glad it's working now.

    Best of luck in the future!
     
  6. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    I do have oneee more thing, if you don't mind of course. For some reason no matter how I calculate the light direction it is never in the proper direction.

    For now I am using "Light.transform.forward" in the script.

    In the shader I use "normalize(-_LightDirection)" and I've done shaders for a while now in Unity and that always seems to work but now it does not.
     
  7. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Light.transform.forward is in world space... make sure to convert it to whatever space you're doing your shading in.
     
  8. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    That's strange. I am shading in world space for sure. Maybe I forgot to convert my normals back to world space from view space.