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
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

The scriptable render pipeline how to support GrabPass?

Discussion in 'Graphics Experimental Previews' started by watsonsong, Mar 12, 2018.

  1. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Hey Phil, Thanks for the answer! I've already seen this feature and the video, but I don't get how it solves the case when I need to dynamically "stack" an arbitrary number of screen grabs. For example, imagine old good `GrabPass {}` inside a shader, that uses `_GrabTexture` to modify the output color. When user adds multiple objects with a material like that on top of each other, they correctly "see" each other. I can't really see how it's possible to implement such behavior with LWRP's custom renderers.
     
  2. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    After fiddling with the latest version of LWRP I was able to finally create a custom render pass, which is invoked after the transparent queue, grabs camera texture, assigns it to a global shader texture property and then renders my custom objects, which are using the grabbed texture.



    It doesn't solve the issue with stacking the objects (which is probably impossible with LWRP after all), though.

    Here is an example, in case anyone is interested (Unity still lacks documentation for this stuff): https://gist.github.com/Elringus/69f0da9c71306f1ea0f575cc7568b31a
     
  3. pastaluego

    pastaluego

    Joined:
    Mar 30, 2017
    Posts:
    196
    Yeah in a 2D game if I wanted a waterfall in the background that distorts only the sprites behind it, and a waterfall in the foreground that distorts only the sprites behind it, I'd need 2 grabpasses, one right before each of those waterfalls are rendered in order to grab the correct screen contents. It works great but 2 grabpasses per frame isn't great. Is there a way with SRP/LWRP to get the screencontents at specific times during the transparent queue in order to replicate that?
     
  4. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    I hope they don't remove the "standard" pipeline, otherwise the ability to grabpass at precise shader render queue is gone forever.
     
  5. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Afaik, they're going to deprecate current rendering system in favor of URP (LWRP previously): https://blogs.unity3d.com/2019/09/20/how-the-lightweight-render-pipeline-is-evolving/

    ...and at the same time not going to make a full-fledged replacement for grabpass (one that will allow stacking the grabpasses). At least, that's how I interpret following paragraph from the aforementioned blog post:

     
  6. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    So basically we have to write an entirely custom render pipeline to get grab pass functionality.
     
  7. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Guess so, but in case when an Asset Store plugin is relying on the grabpass there is just nothing we can do, but prepare to deprecate it, apparently.
     
  8. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    What you mention here is exactly what the old GrabPass would be doing anyway, which is why we removed it, every shader that used it would inject a 'Blit Pass' and write to a texture called _GrabPass, so if you had 5 shaders that used grab pass then you would be doing 5 blits at random points in the rendering cycle which when dealing on mobile hardware you will be severely crippling your rendering efficiency.

    Ideally you render all the stuff you want to appear in this 'Grab Pass' first then do your Blit to capture it to a texture resource, then draw all the objects that need to be transparent/do stuff with it. I agree that this means doing certain effects like heatwaves can look weird if you have a lot of transparencies in your game, so in this case you might want one after the fact, but then we needs another queue after transparents, which is why we are also working on making sure things like this can easily be added via the ScriptableRenderFeature/Pass API.

    This does give me the idea that we should expose some of our built in passes to be used as RenderFeatures as this would mean you could easily add a Copy Color Pass(Grab Pass) after transparent and then use the Render Objects Pass to render your specific shaders/objects that will use it.

    You do not need a custom render pipeline at all, the ScriptableRenderFeature/Pass API would add a way to do it quite easily, but we made a concrete decision in SRP that shaders should not be able to control how the flow of rendering executes.
     
  9. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Thank you for the answer! I'm still a bit confused though. Is it (or will it be at some point) possible to arbitrary "stack" render passes (not via a static pre-configured asset, but dynamically at runtime), where each of that stacked custom pass would save the screen texture (copy color pass?) to a render texture (including the results of any previous custom passes) and draw something using this texture?
     
  10. HoneyButterAlmond

    HoneyButterAlmond

    Joined:
    Oct 27, 2016
    Posts:
    6
    '_CameraOpaqueTexture' with transparent object.

    ForwardRenderers.cs(207)

    Before
    Code (CSharp):
    1.             if (renderingData.cameraData.requiresOpaqueTexture)
    2.             {
    3.                 // TODO: Downsampling method should be store in the renderer isntead of in the asset.
    4.                 // We need to migrate this data to renderer. For now, we query the method in the active asset.
    5.                 Downsampling downsamplingMethod = UniversalRenderPipeline.asset.opaqueDownsampling;
    6.                 m_CopyColorPass.Setup(m_ActiveCameraColorAttachment.Identifier(), m_OpaqueColor, downsamplingMethod);
    7.                 EnqueuePass(m_CopyColorPass);
    8.             }
    9.  
    10.             EnqueuePass(m_RenderTransparentForwardPass);//★ this line
    11.             EnqueuePass(m_OnRenderObjectCallbackPass);
    After
    Code (CSharp):
    1.             EnqueuePass(m_RenderTransparentForwardPass);//★ move to here
    2.  
    3.             if (renderingData.cameraData.requiresOpaqueTexture)
    4.             {
    5.                 // TODO: Downsampling method should be store in the renderer isntead of in the asset.
    6.                 // We need to migrate this data to renderer. For now, we query the method in the active asset.
    7.                 Downsampling downsamplingMethod = UniversalRenderPipeline.asset.opaqueDownsampling;
    8.                 m_CopyColorPass.Setup(m_ActiveCameraColorAttachment.Identifier(), m_OpaqueColor, downsamplingMethod);
    9.                 EnqueuePass(m_CopyColorPass);
    10.             }
    11.  
    12.             EnqueuePass(m_OnRenderObjectCallbackPass);
    before.PNG after.PNG
     
  11. Tona999

    Tona999

    Joined:
    Nov 18, 2015
    Posts:
    6

    For those who do not know, adding a Render Object in the Renderer Features with the "After Rendering Transparents" event does not work. I have Unity 2019.3.9f1.

    I tried this solution and it does indeed solve the problem for 2D sprites as well, which are considered to be transparent objects.

    Isn't this a bug?
    It's also very inconvenient because you have to fix it every time you open Unity.
     
  12. namanam

    namanam

    Joined:
    Jul 27, 2013
    Posts:
    8
    +1

    I NEED RECOPY COLOR AND DEPTH AT SOME TIME,BUT BUGGY, PLEASE SUPPORT.
     
  13. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    I think there might be a fault with the caps lock key on your keyboard.
     
  14. M_O_Marmalade

    M_O_Marmalade

    Joined:
    Jun 4, 2019
    Posts:
    1
    Did you ever find any way to stack transparent objects? I am currently researching a way of doing this, and I would love to be able to continue to work in URP/SRP, but this is a dealbreaker if I can't devise a solution to this issue of stacking transparent objects.
    Being able to inject passes in preset spots during rendering doesn't solve this issue. It creates a limit on the amount of objects that can "see" each other, as you put it. What we need is to be able to inject passes at precise render queue positions.
     
  15. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    They've officially stated, that they won't bring grabpass back, though it's still unclear whether they'll add at least some way to perform dynamic backbuffer sampling to URP or HDRP. I've tried asking many times about that in multiple threads, but they didn't answer even once. I'd suggest posting in this thread with mentions to the related UT members (eg, @Tim-C and @ali_mohebali) with a description of your use case.