Search Unity

Forward Rendering - HDR - Depth Only

Discussion in 'Editor & General Support' started by Chman, Jun 29, 2014.

  1. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    Hello,

    I'm trying to find a way around a limitation (or bug ?) with the forward rendering path. Consider the following dual-camera setup, quite common in FPS games (one camera to render the game and another one on top of it to render the weapons & hud to avoid clipping with the world) :

    Camera 1 - Clear Flags: Solid Color - Depth: 0 - HDR enabled
    Camera 2 - Clear Flags: Depth Only - Depth: 1 - HDR enabled
    Image effects (bloom, tone mapping etc) are applied to the Camera 2.

    This works fine with the deferred rendering path but in forward rendering the output of Camera 1 is truncated to LDR despite it being marked as HDR, so the image effects from Camera 2 can't use the HDR info from Camera 1. According to the documentation, setting HDR on a forward rendered camera will only work if an image effect is present, so I put a dummy post processing effect on it (simple pixel copy so no HDR clamping is done) but it doesn't help either.

    I can't use deferred rendering for various reasons so I'm trying to find a way around this issue. I found a few random posts about it but no solution. I could potentially render Camera 1 to a floating point render target and use it in Camera 2 but I'm not sure it's optimal performance-wise (memory, bandwidth, fillrate).

    Is there anything wrong with this setup ? Is it a limitation of the forward rendering path ? Any workaround ? :)
     
  2. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    I found a "meh" solution :

    I render the two cameras in an ARGBFloat RenderTexture and blit it on screen. It works, the performance hit isn't that bad (although it's still there), it adds 2 draw calls and eat about ~62MB Vram at 1920x1080 and 47MB VRam with ARGBHalf.

    So yeah, it comes with a two critical downsides :
    • Heavy on VRam usage.
    • Doesn't play well with the depth buffer apparently, so no depth-based image effects.
    Which means I need another solution :/

    Any input on this would be appreciated !
     
  3. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    Sorry for the bump, but I'm surprised no one used HDR in a multi-camera setup with forward rendering before. I went through the manual over and over and can't find any reference about why it doesn't work. The only fix I found is to switch to deferred rendering but that's not an option for this project. Any help or explanation about why it doesn't work would be greatly appreciated :)
     
  4. Weltista

    Weltista

    Joined:
    May 6, 2014
    Posts:
    9
    Plus one to the question. I'm also using 2 cameras setup and would like to know if there is a way to come around this (intentional?) limitation. And bump.
     
  5. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    @Weltista Have you found a way around it ?

    I've decided to use an ARGBHalf RenderTexture and manually render both cameras on it. It's not the most optimal setup memory-wise but it works exactly like the dual-camera setup should in this case.

    Edit: A̶c̶t̶u̶a̶l̶l̶y̶ ̶n̶o̶,̶ ̶i̶t̶ ̶d̶o̶e̶s̶n̶'̶t̶ ̶b̶e̶h̶a̶v̶e̶ ̶l̶i̶k̶e̶ ̶a̶ ̶d̶u̶a̶l̶-̶c̶a̶m̶e̶r̶a̶ ̶s̶e̶t̶u̶p̶ ̶w̶o̶u̶l̶d̶ ̶i̶n̶ ̶r̶e̶g̶a̶r̶d̶s̶ ̶t̶o̶ ̶i̶m̶a̶g̶e̶ ̶e̶f̶f̶e̶c̶t̶s̶,̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶r̶e̶n̶d̶e̶r̶i̶n̶g̶ ̶t̶o̶ ̶a̶ ̶t̶e̶x̶t̶u̶r̶e̶ ̶w̶i̶t̶h̶ ̶C̶a̶m̶e̶r̶a̶.̶R̶e̶n̶d̶e̶r̶(̶)̶ ̶d̶o̶e̶s̶n̶'̶t̶ ̶c̶a̶l̶l̶ ̶O̶n̶R̶e̶n̶d̶e̶r̶I̶m̶a̶g̶e̶(̶)̶ ̶s̶o̶ ̶y̶o̶u̶ ̶c̶a̶n̶'̶t̶ ̶a̶p̶p̶l̶y̶ ̶i̶m̶a̶g̶e̶ ̶e̶f̶f̶e̶c̶t̶s̶ ̶t̶o̶ ̶t̶h̶e̶ ̶f̶i̶r̶s̶t̶ ̶c̶a̶m̶e̶r̶a̶ ̶l̶i̶k̶e̶ ̶y̶o̶u̶ ̶w̶o̶u̶l̶d̶ ̶n̶o̶r̶m̶a̶l̶l̶y̶ ̶b̶e̶ ̶a̶b̶l̶e̶ ̶t̶o̶.̶.̶. Image effects are working fine, my mistake !
     
    Last edited: Jul 5, 2014
  6. Weltista

    Weltista

    Joined:
    May 6, 2014
    Posts:
    9
    Hi Chman,

    Your approach with ARGBHalf is interesting -- but I wonder if this will require more processing power, so it would fit for mobile platform?

    And no -- I don't have any way around it myself :(.
     
  7. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    It does require a bit more processing power but not much. The culprit here is the memory usage which would make it a no-go solution for mobiles :/

    You could try it and see how it goes but I wouldn't put too much hope in it.
     
  8. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Hey Chman. Sorry to resurrect an old thread, but is there any chance you could post your code for this camera setup? I've been trying to figure out how to implement the solution you describe here with no luck.
     
  9. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    I'm not using this setup anymore (I switched to deferred), but here's what I did. First, setup your three cameras like this :

    Top Camera
    |- World Camera
    |- Cockpit Camera

    Setting used for each camera :
    1. Top Camera :
      • Enabled : true
      • Clear Flags : solid color
      • Culling Mask : nothing
    2. World Camera :
      • Enabled : false
      • Clear Flags : solid color or skybox
      • Culling Mask : whatever needs to be rendered by this camera
    3. Cockpit Camera :
      • Enabled : false
      • Clear Flags : depth only
      • Culling Mask : whatever needs to be rendered by this camera (on top of World Camera)
    Set Rendering Path to Forward and HDR to true on all cameras.

    On your Top Camera, add a component with some code :

    Code (CSharp):
    1. public Camera WorldCamera;
    2. public Camera CockpitCamera;
    3.  
    4. protected Camera m_MainCamera;
    5. protected RenderTexture m_RenderTexture;
    6.  
    7. void OnEnable()
    8. {
    9.     m_MainCamera = GetComponent<Camera>();
    10. }
    11.  
    12. void OnPreRender()
    13. {
    14.     m_RenderTexture = RenderTexture.GetTemporary((int)m_MainCamera.pixelWidth, (int)m_MainCamera.pixelHeight, 24, RenderTextureFormat.ARGBHalf);
    15.  
    16.     WorldCamera.targetTexture = m_RenderTexture;
    17.     WorldCamera.Render();
    18.     WorldCamera.targetTexture = null;
    19.  
    20.     CockpitCamera.targetTexture = m_RenderTexture;
    21.     CockpitCamera.Render();
    22.     CockpitCamera.targetTexture = null;
    23. }
    24.  
    25. void OnRenderImage(RenderTexture src, RenderTexture dest)
    26. {
    27.     Graphics.Blit(m_RenderTexture, dest);
    28.     RenderTexture.ReleaseTemporary(m_RenderTexture);
    29. }
    Populate the WorldCamera and CockpitCamera fields in the inspector and you should be good to go. Your HDR image effects should be on Top Camera (Tonemapping etc) just after this component.

    Yeah, it's ugly and eats some VRam but it works :eek: If you have Unity 5, I'd recommend using the deferred rendering path (the new one, not the legacy one).
     
    Last edited: Feb 25, 2015
  10. Nimred

    Nimred

    Joined:
    Nov 1, 2014
    Posts:
    46
    I have the same HDR issue, thanks for posting the workaround. It definitely works, though my camera started inverting itself randomly after I started using this - haven't investigated why yet.

    In case someone else is affected by the broken HDR bug (when in forward rendering, and using the "Depth Only" clear flag), here's the link to the relevant issue. Please vote on it so it gets looked at faster. The description doesn't match exactly but my exact bug report was resolved as duplicate of this more general one:

    https://issuetracker.unity3d.com/is...s-hdr-or-deferred-equals-equals-failure-cases
     
  11. BlankMauser

    BlankMauser

    Joined:
    Dec 10, 2013
    Posts:
    138
    It says a "Fix in review." Its 2018 now. Is this issue still going to be fixed? I really want to reap both the benefits of HDR and Forward Rendering. As I use very few dynamic lights in my scenes. However I use multiple cameras for a lot of depth tricks.