Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Transparent objects not working with DOF

Discussion in 'Graphics Experimental Previews' started by EnriqueGato, Jan 24, 2019.

  1. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    These are definitions extracted from the Frame Settings docs.
    • Transparent Prepass: Tick this checkbox to enable Transparent Prepass. Enabling this feature causes HDRP to add polygons from transparent Materials to the depth buffer to improve sorting.
    • Transparent Postpass: Tick this checkbox to enable Transparent Postpass. Enabling this feature causes HDRP to add polygons to the depth buffer that postprocessing uses.
    I get from this that activating these options I could get transparent objects to render nice when DOF is enabled, but they appear blured as if the weren't writing anything on the depht channel.

    Am I misinterpreting those options? How can I get transparent objects to render DOF nice in HDRP?
     
    Last edited: Jan 24, 2019
  2. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    No one? I honestly think there's some kind of problem here. I've tried every single "Transparent Prepass/Postpass" option I've found in the GameObject, in the Frame Settings for the camera (both Rendering Passes an Rendering Settings), Forward and Deferred rendering... No way to get Depth of Field work right with transparent objects.
     
  3. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    I didn't use any of those yet and I'm still on 4.6, so I don't know if my information is of help to you.
    When MSAA and Forward are active the CameraDepthTexture is not filled correctly. I added a quick MSAA resolve to fix it for me.

    I don't have the time to put a patch together or anything, but the main changes are in here:
    Code (CSharp):
    1. void CopyDepthBufferIfNeeded(HDCamera hdCamera, CommandBuffer cmd)
    2. {
    3.     if (!m_IsDepthBufferCopyValid)
    4.     {
    5.         using (new ProfilingSample(cmd, "Copy depth buffer", CustomSamplerId.CopyDepthBuffer.GetSampler()))
    6.         {
    7.             if(hdCamera.frameSettings.enableMSAA)
    8.             {
    9.                 var rect = new Rect(0, 0, hdCamera.actualWidth, hdCamera.actualHeight);
    10.                 m_SharedRTManager.ResolveMSAADepth(cmd, hdCamera, m_SharedRTManager.GetDepthStencilBuffer(true), m_SharedRTManager.GetDepthTexture(false), rect);
    11.                 m_IsDepthBufferCopyValid = true;
    12.             }
    13.             else
    14.             {
    15.                 // TODO: maybe we don't actually need the top MIP level?
    16.                 // That way we could avoid making the copy, and build the MIP hierarchy directly.
    17.                 // The downside is that our SSR tracing accuracy would decrease a little bit.
    18.                 // But since we never render SSR at full resolution, this may be acceptable.
    19.  
    20.                 // TODO: reading the depth buffer with a compute shader will cause it to decompress in place.
    21.                 // On console, to preserve the depth test performance, we must NOT decompress the 'm_CameraDepthStencilBuffer' in place.
    22.                 // We should call decompressDepthSurfaceToCopy() and decompress it to 'm_CameraDepthBufferMipChain'.
    23.                 m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), new RectInt(0, 0, m_CurrentWidth, m_CurrentHeight));
    24.             }
    25.         }
    26.         m_IsDepthBufferCopyValid = true;
    27.     }
    28. }
    29.  
    30. public void ResolveMSAADepth(CommandBuffer cmd, HDCamera hdCamera, RTHandleSystem.RTHandle msaaTarget, RTHandleSystem.RTHandle simpleTarget, Rect rect)
    31. {
    32.     if (hdCamera.frameSettings.enableMSAA)
    33.     {
    34.         Debug.Assert(m_MSAASupported);
    35.         using (new ProfilingSample(cmd, "ResolveDepth", CustomSamplerId.VolumeUpdate.GetSampler()))
    36.         {
    37.             // Grab the RTIs and set the output render targets
    38.             HDUtils.SetRenderTarget(cmd, hdCamera, simpleTarget);
    39.  
    40.             // Set the input textures
    41.             m_PropertyBlock.SetTexture(HDShaderIDs._DepthTextureMS, msaaTarget);
    42.  
    43.             cmd.SetViewport(rect);
    44.  
    45.             // Resolve the depth and normal buffers
    46.             cmd.DrawProcedural(Matrix4x4.identity, m_DepthResolveMaterial, SampleCountToPassIndex(m_MSAASamples), MeshTopology.Triangles, 3, 1, m_PropertyBlock);
    47.         }
    48.     }
    49. }
     
  4. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    DOF never did work with transparency because transparent pass doesn't render depth information (and can't, obviously) which DOF requires. So if you ever saw this working it was because the geometry behind transparent objects supplied near enough depth.

    There are a bunch of workarounds, you have to choose which one you'd like to do though as it's basically a limitation for all engines, with a set of workarounds.
     
  5. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    That's what transparent depth postpass is for.
     
    EnriqueGato likes this.
  6. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    I'm sorry, my reply is probably useless, I confused it with another, msaa related, similar problem.

    Did you check, that postpass support is not only activated in the pipeline asset but that it is also enabled for the camera?
     
    EnriqueGato likes this.
  7. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    It should work, depth postpass writes transparent's depths into the depth buffer right before postprocessing and depth of field is executed but it looks like MSAA is not correctly handled. Is MSAA turned off?
     
    hippocoder likes this.
  8. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    What are those Transparent Prepass/Postpass options for then?

    That's what I was figuring out from the docs.

    I think I've setup everything right, but I'll do a couple of simple tests in an isolated scene to be 100% sure. I'll let you know the results.
     
  9. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    I'm not very sure how to get this with workarounds. I read about a double camera system, but I'm not sure this is the right one. Which is the one suggested for Unity?
     
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    HDRP should support doing this, perhaps I misunderstood ?
     
  11. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    Hi,

    Transparent Prepass and Transparent Postpass are here to help. But I suppose you forget to control them with alpha clip threshold.

    Transparent Prepass is executed and fill the depth buffer, then regular transparent rendering is done, then Transparent Postpass is executed and fill again the depth buffer.

    The DOF is based on depth buffer, so it read the lastest depth buffer and use that for postprocessing allowing to have DOF on transparent objects.


    Transparent Prepass is used to improve sorting of almost opaque transparent (i.e transparent object that have an opacity of nearly 1).

    For example Alpha blended hair card. In this context the root of the hair card are opaque (opacity 1) and the end are fully transparent (opacity 0). To help improve sorting between hair card we want to consider opacity > threshold as opaque. This threshold is Prepass Alpha clipping Threshold and usually setup around 0.9.

    Transparent Postpass is used to fill depth buffer for postprocess like DOF.
    You need to control the Postpass Alpha Clipping Threshold to say which part of the transparent object write in depth. If we take the example of hair card above we will use something like 0.2 to be sure hair are part of dof (but this can create halo so you need to tweak it carefully).
     
    Onigiri likes this.
  12. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    I get DOF working with transparent objects using Transparent Postpass as described, but if I also want raytraced ScreenSpaceReflections (SSR) on them (glas facade of a building) - no way:

    Objects behind the glas get rendered sharp:

    upload_2022-5-17_13-9-44.png

    Is that not possible?
     
  13. TheWanderingBen

    TheWanderingBen

    Joined:
    Nov 3, 2015
    Posts:
    98
    Hi @SebLagarde, I'm having a similar issue with a Custom Pass not getting transparent depth, even though all my settings are correct. I've tried adjusting the Alpha Cutoffs and still nothing. My Custom Pass is in Before Post Process but is still getting the old depth buffer.

    If I break into the source, it seems like my frame settings are fine, and that RenderTransparentDepthPostpass is getting to the meat of the function:
    upload_2023-1-3_15-52-12.png

    But sampling the depth buffer in my Custom Pass, I still don't see the transparent objects (even though it does indeed get called after the depth is written here).

    Any ideas what I could be doing wrong?
     
  14. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    I see the same problem. I even use a dedicated renderobjects pass and for the love of god, I cannot make my objects show up in the depth texture.

    This is BS, Unity. Depth Texture needs to be reliably writable (and actually also clearable!) during any render stage by the user. If I set it to After Transparents, then DEFINITELY have my stuff that renders in After or at the very least BeforeTransparents show up in the depth buffer / texture.

    Unity 2023.2, by the way.
     
  15. TheWanderingBen

    TheWanderingBen

    Joined:
    Nov 3, 2015
    Posts:
    98
    I ended up writing to a separate Depth Buffer using another Custom Pass.

    Not ideal, but maybe could work for you too, @Thygrrr
     
  16. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    I did something similar, but for generally transparent objects such as 3D Holo elements in the UI, they feel like transparent glass. A separate buffer could fix this.

    But I'll probably go with a separate blit pass for transparent objects altogether.