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

The scriptable render pipeline how to support GrabPass?

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

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I am write a custom SRP, but the game view can not deal with GrabPass. How can I fix it?
    The unity report the error:

    Shader properties can't be added to this global property sheet. Trying to add _Refraction (type 3 count 1)
    UnityEngine.Experimental.Rendering.ScriptableRenderContext:Submit()
    Game.MobileRenderPipeline:Render(ScriptableRenderContext, Camera[]) (at Assets/Game/Scripts/Rendering/MobileRenderPipeline.cs:224)
    UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
     
    Last edited: Mar 13, 2018
  2. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    BTW, I test grab pass on LightWeightRenderPipeline, it report the same error:

    Shader properties can't be added to this global property sheet. Trying to add _Refraction (type 3 count 1)
    UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)


    And the LightWeightRenderPipeline seems has compile error for Unity 2018.1.0b9.
     
  3. hadynlander

    hadynlander

    Joined:
    Jan 24, 2014
    Posts:
    41
  4. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    We are testing an alternative in GrabPass in LWRP that will expose the Camera color texture after rendering opaques. That should cover majority of cases I believe.
     
    AlejMC, Mauri, FROS7 and 3 others like this.
  5. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    @phil_lira, I am working on my own SRP and try to render the opaque to a render texture when there has any object after camera culled with the material that require the opaque texture. How can I check this, I don't want to render the opaque texture when there have no any renderer in the cull set require the grabpass.
     
  6. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    This might help:

    https://forum.unity.com/threads/graphics-blit-vs-grabpass-vs-rendertexture.523825/

    Talks about 2 other ways to do same as grabpass
     
  7. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    @watson
    When issuing a DrawRenderers command you will pass in a FilterRenderingSettings in which you can configure a renderQueueRange. You can configure your special grabpass material with a specific renderQueue and filter with that. Upon calling DrawRenderers it will sweep through all renderers that survived culling and other things like this filter settings.

    https://docs.unity3d.com/2018.1/Doc...ng.ScriptableRenderContext.DrawRenderers.html

    https://docs.unity3d.com/2018.1/Doc...mental.Rendering.FilterRenderersSettings.html
     
  8. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,906
    Any update on this?
     
  9. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    We have it in the LWRP branch on the SRP git but as it was put in too late in the 2018.1 beta cycle it won't be making it into the LW packages just yet. Also we haven't fully tested it in all scenarios and want to make sure it works well. But so far it's pretty good and much more efficient than the legacy grabpass, a bit more limiting as it doesn't contain transparent objects but the performance improvements more than make up for that downside.
     
    FROS7 likes this.
  10. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,906
    Thanks! Keep up the good work.

    So is it implemented as a global "GrabPass" texture available after opaque objects have been rendered? What's the uniform name?
     
    Last edited: Apr 18, 2018
  11. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Wait is legacy GrabPass contain transparent objects?
     
  12. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    This went through a few hefty discussions but to align it best with the current naming of _CameraDepthTexture we settled for _CameraOpaqueTexture

    The legacy GrabPass would get it at the specific point your shader needed it, so this is why it had the potential of being quite inefficient as you could end up with multiple ones created at different times in the frames rendering. The way LW pipe handles it is we just create the one after opaque objects are rendered since this covers the majority of use cases(heat distortion, frosted glass, water refractions etc) and guarantees theres only one render texture reserved and one Blit performed.
     
  13. equalsequals

    equalsequals

    Joined:
    Sep 27, 2010
    Posts:
    154
    Just a suggestion for this as we've already implemented this in our local branch of SRP, but the ability to choose the grab pass to be downsampled could be helpful for performance and straight-forward to implement.
     
  14. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    We have already done this actually in our implementation, you will have the option of no downsampling, 2xBilinear filter, 4xBox filter, 4xBilinear filter.
     
    AlejMC, Peter77, equalsequals and 2 others like this.
  15. TimNedvyga

    TimNedvyga

    Joined:
    May 18, 2015
    Posts:
    96
    Hi,
    will we see this soon?
     
  16. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    In the coming weeks, we are hoping to get something out for Unite Berlin, but no promises :)
     
  17. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    Hi Andre,
    Can _CameraOpaqueTexture be accessed via shader graph?
    Also I'm writing a shader using this (via lightweight render pipeline) and I'm finding the _CameraOpaqueTexture is only grabbing geometry. Is it possible to grab what the camera sees? Such as sprites and particles?
    I am in a 2D project at the moment.
     
    Last edited: Jul 7, 2018
  18. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    Currently not, we are trying to decide how to support Pipeline specific features in a clean way(since _CameraOpaqueTexture does not exist in HDRP, or any Custom RP anyone makes)

    As the way the _CameraOpaqueTexture is created it will only capture things in the Opaque pass, this is done for speed and usability, unfortunately sprites are rendered in the transparent pass. In saying that we are adding some very very cool functionality to the pipeline right now, which will give you the ability to add your own pass very easily at any point of the rendering to do what you want, I'm also helping out with documentation so I will make sure there is a good use case sample which is something like this.
     
    AlejMC likes this.
  19. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    I notice _CameraOpaqueTexture is in the 2.0.0-preview changelog on Github but the latest version in the package manager is 1.1.4.

    1. Any ETA on this being released to preview on the package manager?
    2. Is it reasonably safe to grab the github version for a project that is still in the prototype stage?
    3. Is this backwards compatible to 2018.1.x or do we need to be using 2018.2?
     
  20. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Hi Andybak. 2.0.x is already available and has been for some time. It requires 2018.2 though. If you use 2018.2 it will just showup there for you in package manager.
     
    AlejMC likes this.
  21. HopelessHyena

    HopelessHyena

    Joined:
    May 26, 2015
    Posts:
    18
    @Tim-C Would you mind providing detail on how one can go about mapping the _CameraOpaqueTexture correctly onto a mesh as if to mimic a grab pass (namely, the graphics rendered behind the mesh are rendered in the correct location(s) on the mesh).

    I have been able to access the texture but I can't work out how to correctly position it on the object. Any help would be greatly appreciated, as I am also trying to create a water shader similar to the one made (in the shader graph) here . Many thanks in advance!
     
  22. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    Awesome - thankyou!!!
     
  23. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    Are there any plans to make command buffers executable at an integer queue rather than the predefined list of enums? Right now it's really hard/impossible to get a command buffer to execute before a custom shader. Will SRP solve this problem?
     
    INeatFreak and bluescrn like this.
  24. AlejMC

    AlejMC

    Joined:
    Oct 15, 2013
    Posts:
    149
    this is GREAT news, will test that camera opaque texture asap.
    Amazing that downsampling options are included.
     
  25. Andy-Touch

    Andy-Touch

    A Moon Shaped Bool Unity Legend

    Joined:
    May 5, 2014
    Posts:
    1,485
    Hey Grab Pass folks!

    To access
    _CameraOpaqueTexture
    you must first enable it in the LWRP Asset. There are also some options for different Downsampling qualities.



    To access it in Shader Graph; you can then create a Texture Property, and then use
    _CameraOpaqueTexture
    in the reference field. You will also have to disable the Texture Property from being exposed, otherwise this will likely be overriden by the Material Inspector.

    Once the Property is Samples using the 'Sample Texture 2D' node, you can use it for GrabPass-like effects!

    Here is a really simple Shader Graph setup:



    Which, when applied to this 'screen' will cause a repeated sample (Im applying it to a primitive quad so the camera texture will stretch to fill the mesh):



    However, you can also use the Screen Position Node in Shader Graph, so that instead of drawing the whole camera onto the mesh, you instead remap the UV used by the texture for what area of the screen the mesh 'uses':



    Which will result in being able to see objects on the side of the screen (In this case; a barrel). It is important to note that you currently have to switch the Shader to 'Transparent' so that it is drawn after Opaque Pass.


    And then you can use all kinds of effects, in Shader Graph, on the camera texture:



    Including Noise Distortion (One of the most common uses for Grab Pass; especially for particle explosions!):





    It is also possible to get the
    _CameraDepthTexture
    aswell; Just enable Depth Texture on the LWRP Asset and use
    _CameraDepthTexture
    for the Texture Property reference. :)



    AFAIK; all of this works in the same way if you were writing shaders for LWRP, instead of using Shader Graph.
     
    Last edited: Dec 21, 2018
    konsic, cym_hellfire, Peter77 and 3 others like this.
  26. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Hey Andy, Thanks for keeping us updated! It's great news, though I'm more interested in a way to also grab transparent passes; is this still impossible to achieve with the SRP?
     
  27. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    In LWRP you can do it by injecting a custom render pass after rendering transparents.

    @Andy-Touch has a GitHub with examples injecting custom render pass after opaques. The concept is the same you just have to replace the IAfterOpaque for an IAfterTransparent
     
    dadude123 and Elringus like this.
  28. Andy-Touch

    Andy-Touch

    A Moon Shaped Bool Unity Legend

    Joined:
    May 5, 2014
    Posts:
    1,485
    https://github.com/UnityTechnologies/LWRPScriptableRenderPass_ExampleLibrary :)

    In DemoScene_ScreenEffect; you should be able to modify the example(s) with Felipe's suggestions. :)
     
    Last edited: Dec 21, 2018
    dadude123 and Elringus like this.
  29. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Wow, didn't know it's already implemented. Super nice feature, thank you guys!
     
  30. ChaoticBox

    ChaoticBox

    Joined:
    Mar 6, 2015
    Posts:
    6
    Is there a way to grab the screen at any time though? _CameraOpaqueTexture still won't contain transparent objects right? Either way I can't see how this could handle transparent objects both behind and in front of the effect - not even simultaneously, just in general.
     
    INeatFreak likes this.
  31. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Implement IAfterTransparent and IAfterOpaque both?
     
  32. cym_hellfire

    cym_hellfire

    Joined:
    Aug 18, 2017
    Posts:
    11
    Hi, Andy. I try to follow the sample project and grab the screen like the ScreenEffectPass do. But it's not work in my project even thought I copy and paste the ScreenEffectPass.cs into my repository. I've added this script to my main camera and saw the tag in Profiler view. Seems the script is working, but the _GrabTexture is always a grey texture unlike the sample's. I'm wondering if I missed some configuration steps to make it work.

    By the way, I just enabled the LWRP and Shader Graph packages in my project. Do you have any idea about this? Thank you.
     
  33. cym_hellfire

    cym_hellfire

    Joined:
    Aug 18, 2017
    Posts:
    11
    Seems I must enter the Play mode to get the correct result. After I remove and add the script to camera several times, it works correctly. Still have no idea about this issue.
     
  34. owlhoot

    owlhoot

    Joined:
    Jan 23, 2019
    Posts:
    1
    Hi, I just changed Pass on 'IAfterTransparentPass' in your script and it looks like this in Play Mode. What do you think? 1.png 2.png 3.png
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Experimental.Rendering;
    5. using UnityEngine.Experimental.Rendering.LightweightPipeline;
    6. using UnityEngine.Rendering;
    7.  
    8. [ExecuteInEditMode]
    9. [ImageEffectAllowedInSceneView]
    10. public class ScreenEffectPass : MonoBehaviour, IAfterTransparentPass
    11. {
    12.  
    13.     private ScreenEffectPassImpl m_grabPass;
    14.  
    15.     public ScriptableRenderPass GetPassToEnqueue(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorHandle, RenderTargetHandle depthHandle)
    16.     {
    17.         if (m_grabPass == null)
    18.             m_grabPass = new ScreenEffectPassImpl(colorHandle);
    19.  
    20.         return m_grabPass;
    21.     }
    22.  
    23. }
    24.  
    25.  
    26. public class ScreenEffectPassImpl : ScriptableRenderPass
    27. {
    28.     const string k_RenderGrabPassTag = "Screen Effect Pass";
    29.  
    30.  
    31.     private RenderTextureDescriptor m_BaseDescriptor;
    32.     private RenderTargetHandle m_ColorHandle;
    33.  
    34.     public ScreenEffectPassImpl(RenderTargetHandle colorHandle)
    35.     {
    36.         m_ColorHandle = colorHandle;
    37.     }
    38.  
    39.     public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData)
    40.     {
    41.         CommandBuffer buf = CommandBufferPool.Get(k_RenderGrabPassTag);
    42.  
    43.         using (new ProfilingSample(buf, k_RenderGrabPassTag))
    44.         {
    45.            
    46.             // copy screen into temporary RT
    47.             int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
    48.             RenderTextureDescriptor opaqueDesc = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData);
    49.             buf.GetTemporaryRT(screenCopyID, opaqueDesc, FilterMode.Bilinear);
    50.             buf.Blit(m_ColorHandle.Identifier(), screenCopyID);
    51.  
    52.  
    53.  
    54.             //Set Texture for Shader Graph
    55.             buf.SetGlobalTexture("_GrabTexture", screenCopyID);
    56.         }
    57.  
    58.         context.ExecuteCommandBuffer(buf);
    59.         CommandBufferPool.Release(buf);
    60.     }
    61. }
    62.  
     
    phil_lira likes this.
  35. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    228
  36. Micodemo1

    Micodemo1

    Joined:
    Aug 16, 2017
    Posts:
    1

    Hey there! when I try to implement this method it only ever uses the scene view camera and not the game camera, even in play mode after being built! is there any way to fix this? otherwise it is just grey when built.
     
  37. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    This sounds like it is disabled on the LWRP asset, especially if it is grey on the built player. Make sure it is turned on there, also depending on LWRP version you will need to add/enable it to the camera.

    This looks like a classic case of the material being 'Opaque' and not 'Transparent' since it tries to render itself onto itself, thus infinitely doubling up over and over again. Make sure the ShaderGraph master node is set to transparent type and recompile(save).
     
  38. pikamus

    pikamus

    Joined:
    Oct 27, 2012
    Posts:
    6
    Just trying this out, works fine in the editor, but doesn't seem to work on my galaxy s8 (android). any ideas?

    Also I have the rendering API set to gles 3.0
     
  39. pikamus

    pikamus

    Joined:
    Oct 27, 2012
    Posts:
    6
    Okay, so the shader works on meshes, etc in the editor and device (android). Just not on UI objects on android. Any ideas?
     
  40. Pimpace

    Pimpace

    Joined:
    Sep 21, 2017
    Posts:
    41
    How can I use this like a full screen post process effect. I mean as you showed we can make a shader in Shadergraph which has some camera effect like blur, UV distort, etc. But how can I use this shader for a full screen camera effect? With a second camera? Any suggestion?
     
  41. cuddlepunk

    cuddlepunk

    Joined:
    Apr 9, 2014
    Posts:
    18
    small question,

    It's been noted above that it's possible to generate textures after the opaque and transparent render pass; IAfterTransparent and IAfterOpaque. Though my question is whether it's possible to design and implement custom render pass lists?

    My game is from a fixed camera perspective, so I thought it may be possible group certain meshes into render passes based on their respective distance from the camera, allowing me to simulate _Grabpass. Currently, the light-weight render pipeline supports a single Opaque Pass, how possible would be to create additional opaque passes?


    My only concern is that I'm pretty new to this, and have no knowledge about setting this up.
     
    Last edited: Apr 4, 2019
  42. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    You could make a screen sized quad and stick it directly in front of the camera so that it takes up the entire screen
     
  43. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    catherineomega likes this.
  44. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    Grab pass sure was convenient, and it allowed capturing the screen at an arbitrary shader render queue, something the new scriptable render pipelines can't do... hope it will come back for SRP.
     
  45. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Completely agree. While scriptable render passes allow to grab the camera texture once at specific points (before/after opaque/transparent, etc), there are still situations when we need to perform the grab multiple times per frame before executing specific shaders (eg, one of my asset store packages depends on this and it has quite a lot of users). Afaik, neither LWRP nor HDRP allows this by design. Considering the plans of replacing current render system with SRP, this looks troublesome...

    Would really love to hear any comments on this situation from the Unity stuff @phil_lira @Andy-Touch @Andre_Mcgrail
     
    INeatFreak, Gekigengar and a436t4ataf like this.
  46. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    I also don't like having to use command buffers. It seems like a System.Action or something similar would be better and just simply use Graphics.* to do the work. This would allow more complex rendering code and would have access to the latest and up to date script variables, texture references, etc. without having to re-create or setup a command buffer every frame.
     
  47. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    So, LWRP is now "stable" and users are widely adopting it, but... It's impossible to implement some of the effects, that were using GrabPass on the old rendering system. I'm talking about situations when we were able to grab screen texture before executing a shader pass, which allowed to "stack" multiple effects. Afaik, it's not possible at all with the LWRP. (or am I missing something?)

    Here is a thread that touches the same subject, but again, without a solution: https://forum.unity.com/threads/srp-and-grabpass-with-transparent.555892/

    @phil_lira @Andy-Touch @Andre_Mcgrail @Tim-C
     
    Last edited: May 26, 2019
    INeatFreak, Gekigengar and a436t4ataf like this.
  48. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    Not out of the box without writing your own forked version of LWRP pipeline.
     
  49. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Which is impossible, as I need that for an Asset Store package, which should support the built-in SRPs. :(
     
    a436t4ataf likes this.
  50. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    Hey sorry. I hadn't seen the notification for this post for some reason.

    Right so it's easy to do now with lwrp. 5.16.1 is out today and it comes with a menu to create a render pass template. This is a script that lives in your project all you have to do is call a blit with a shader that reads _CameraColorTexture and blits to your grabpass.

    The menu is in Asset / Create / Render Pipeline / Lightweight Render Pipeline / Custom Renderer Feature.

    Once you have this you create a renderer and insert the grabpass as much times as you want in specific place. Then you share your renderer with your users. They just need to assign your renderer to the pipeline asset

    Here's a video showing how to create custom renderers and inject render passes on it
     
    VirtusH, cuddlepunk and hadynlander like this.