Search Unity

How to change light/shadowmap rendertarget to MRTs

Discussion in 'Shaders' started by Gentlymad, Aug 4, 2016.

  1. Gentlymad

    Gentlymad

    Joined:
    Nov 11, 2014
    Posts:
    16
    1.)
    We are currently trying to implement Reflective Shadow Maps into Unity and have a hard time using the build-in directional light for this.
    We need the directional light to use multiple render targets instead of just one in order to make RSM work.

    How can we do that? We tried using a CommandBuffer for this, but it's not working. The light is still rendering to it's own rendertarget instead of the supplied MRTs.

    Code (CSharp):
    1. light = GetComponent<Light>();
    2.  
    3. CommandBuffer cBuffer = new CommandBuffer();
    4.  
    5. RenderTargetIdentifier depth = new RenderTargetIdentifier(new RenderTexture(512, 512, 24, RenderTextureFormat.Depth));
    6. RenderTargetIdentifier shadowmap = new RenderTargetIdentifier(new RenderTexture(512, 512, 24, RenderTextureFormat.RFloat));
    7. RenderTargetIdentifier wPos = new RenderTargetIdentifier(new RenderTexture(512, 512, 24, RenderTextureFormat.ARGBFloat));
    8. RenderTargetIdentifier normals = new RenderTargetIdentifier(new RenderTexture(512, 512, 24, RenderTextureFormat.ARGB2101010));
    9.  
    10. cBuffer.SetGlobalTexture("_RSMShadowmap", shadowmap);
    11. cBuffer.SetGlobalTexture("_RSMPosition", wPos);
    12. cBuffer.SetGlobalTexture("_RSMNormals", normals);
    13.  
    14. RenderTargetIdentifier[] rti = {shadowmap, wPos, normals};
    15. cBuffer.SetRenderTarget(rti, depth);
    16.  
    17. light.AddCommandBuffer(UnityEngine.Rendering.LightEvent.BeforeShadowMap, cBuffer);
    If it makes any difference: For the type of game we are working on, Cascaded Shadow Maps are not needed. We can use "simple" shadowmapping with projection set to close fit.


    2.)
    If i ever get MRTs working for the light, i am not sure how to get the light to render custom output into them. Replacement Shaders seem to be the way to go, but i have not yet found out how i can replace the light depthmap shader for all objects. If worst comes to worst, i could just make some changes to UnityCG.cginc, AutoLight.cginc and other .cgincs where it is needed, but i'd prefer not to do that so we can safely update Unity in the future without the need to always rewrite/update .cginc files.


    Any help is greatly appreciated :)
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Short version: You can't.

    Longer version: You can't use Unity's built in lighting system to do this, you have to write your own that fully replaces Unity's lighting system, lit shaders, and setting of relevant variables on the shaders. See Valve's Lab Renderer for an example of this. To use MRTs you'll need to render your shadow maps using a camera with SetTargetBuffers() used to assign multiple textures.
    https://docs.unity3d.com/ScriptReference/Camera.SetTargetBuffers.html