Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Custom pass rendering from disabled camera has incorrect culling results

Discussion in 'High Definition Render Pipeline' started by mgeorgedeveloper, Oct 12, 2023.

  1. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    (Using Unity 2022.3.8, HDRP 14)

    I have a custom pass that uses CustomPassUtils.RenderFromCamera() to render a disabled camera to a RenderTexture. This works well, allowing me to render objects based on layer mask, using a custom material, into a render texture, from the point of view of the disabled camera. Great feature.

    The only nagging issue I have, is that only objects that are also visible to the main camera (game view), will be considered when rendering from the second disabled camera.

    I then came across some example code to set the cullingResults on the camera we are rendering from. It looks like this:

    CustomPassCullingResults.png

    However, it seems to have no effect... as soon as the main game view camera looks away from the area, the custom pass results are blank. If the main camera's view overlaps that of the secondary disabled camera, the RT is filled with correct output as seen from the disabled cam.

    I'm suspecting this is a bug, but if not, please advise if there is some work-around or I'm just doing it wrong.

    Thanks!
     
    Last edited: Oct 12, 2023
    nchernyadev likes this.
  2. nehvaleem

    nehvaleem

    Joined:
    Dec 13, 2012
    Posts:
    420
    I might be wrong, but I think that I read somewhere that this is intended. If not - it would be a really viable workaround for HDRP having troubles with multiple cameras.
     
  3. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    Not sure about this - the block of code that gets the refreshed culling list seems to work just fine, and doesn't have a big overhead at all.

    I don't think the prohibiting overheads of a second active camera relates purely to getting new culling results? In my limited understanding, this has more to do with the total workflow (setup work + dozens of passes) happening per active camera. Out of this total work, getting culling results is just a small part.

    HDPR-all-passes.png

    In contrast, doing a custom pass from a disabled camera's viewpoint, only touches on one custom pass injection point above, even if we try to get refreshed culling results for this camera's viewpoint. Having a second active camera, invokes the entire workflow above (depending of course on Frame Settings).
     
  4. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
  5. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    Hi folks, I just wanted to bump this one more time to see if somebody from Unity can cast some light on the issue? Even a confirmation that the custom culling results won't work as shown in the above example, will help. Thanks!
     
    nchernyadev likes this.
  6. ekakiya

    ekakiya

    Joined:
    Jul 25, 2011
    Posts:
    79
    Maybe you can use CullingOptions.ForceEvenIfCameraIsNotActive option.
    It works fine on custom RP, It was used on old HDRP, but not on current HDRP.
     
    mgeorgedeveloper likes this.
  7. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    249
    Hello,

    Indeed, the CustomPassUtils.RenderFromCamera function is supposed to use the culling results you set in the context to draw the objects. From what you're seeing it looks like the culling result you set in the context is being ignored which is weird because we use it directly to do the DrawRenderers call with the camera matrices override.

    I tried to repro in the HDRP-Custom-Passes project with Unity 2022.3.8 using the camera depth bake scene (I moved away the main camera from the level) but it seems to work correctly for me (object in the render texture are still rendered fine even if they are not in the main camera view).

    Could you provide a bit more context about what you're doing in your custom pass or scene setup? Maybe there is something else affecting the result of your pass.
     
  8. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    The best I can do is post the entire custom pass code (attached).

    It's a pretty straight forward thing, just trying to render into a render texture, using a disabled camera, with a particular layer mask and so on.

    The whole thing works, so long as the objects we're trying to render is also in view of the main game camera. I can "blank out" the RT result by simply rotating the main game camera to look elsewhere.

    If this truly does seem weird and you are saying the custom culling should work, then I will need to recreate a minimal repro project. I wonder if this is somehow related to the particular Unity version (2022.3.8, or nearby versions).
     

    Attached Files:

  9. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    Maybe this will help - some screenshots showing exactly what happens when the game view sees the boxes, vs. not seeing the boxes.

    The custom pass does this:
    - Rendering the boxes and terrain (the layer mask "Ignore Raycast" in this test)...
    - ... from the point of view of the disabled cam...
    - ... using the culling mask "Ignore Raycast" (just a test)...
    - ... using the DepthCaptureMaterial override material...
    - ... into the DepthCaptureA_RT render texture.

    Working:
    render-from-cam-1.png

    Not working:
    render-from-cam-2.png

    Info about the custom pass setup:
    render-from-cam-3.png
     
    Last edited: Oct 30, 2023
  10. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    249
    Hum, I think that your script is not modifying the cullingResults in the CustomPassContext.
    CustomPassContext is a struct so every time you pass it as a parameter, it does a copy. So when you pass it to your
    PrepareToExecute to override the culling, you actually change its copy and not the context from the Execute function.

    Can you try to pass the custom pass context as ref in your function and see if it fixes the issue?
     
  11. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    308
    Thanks so much, it works now. It never occurred to me even for a millisecond that CustomPassContext might be a struct. Well, now I know :)
     
    Last edited: Oct 31, 2023
    antoinel_unity likes this.
  12. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    249
    Most of our API uses structs to avoid any GC alloc during the frame :) But yeah it comes with a bit more complexity in the code.