Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

Fullscreen blur with URP

Discussion in 'Universal Render Pipeline' started by Dizzy-Dalvin, May 6, 2020.

  1. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    We've just switched our project from the built-in rendering to URP because our artist needs it to use Shader Graph. After fixing all the materials and the camera settings, everything seems to be working fine except for the full-screen blur we were using.

    This is our setup before the transition:
    - Background Camera
    - Main 3D Camera
    - Main UI Camera
    - Blur Camera
    - Foreground UI Camera
    - Tooltip Camera

    Blur Camera didn't render any objects, it just had the following script on it:
    Code (CSharp):
    1. private void OnRenderImage(RenderTexture source, RenderTexture destination)
    2. {
    3.     var temporaryTexture = RenderTexture.GetTemporary(source.width, source.height);
    4.  
    5.     Graphics.Blit(source, temporaryTexture, _material, pass: 0);
    6.     Graphics.Blit(temporaryTexture, destination, _material, pass: 1);
    7.  
    8.     RenderTexture.ReleaseTemporary(temporaryTexture);
    9. }
    This way everything except for the foreground UI and the tooltips was blurred when we enabled this camera.

    Now, as I understand, OnRenderImage will not work with URP. So how do I achieve the same effect? I've very little experience working with graphics but as I see it I just need a place to plug the old blur shader. Could you please help me or at least point me in the right direction?

    I'm using Unity 2019.3.12f1 and URP 7.3.1.
     
  2. peterbay

    peterbay

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    49
  3. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    I've created a ScriptableRenderPass script and I guess I'm supposed to implement the Execute method and use ScriptableRenderContext somehow but I don't exactly understand what I should do with it. Is there a code example somewhere maybe?
     
  4. jsjdev91

    jsjdev91

    Joined:
    Dec 17, 2019
    Posts:
    4
  5. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    Thanks. I've been able to apply it to full screen but I still can't figure out how to make it apply to the camera I need. It seems that depending on renderPassEvent it is applied either before the last camera or after all the cameras but I need it specifically between Main UI Camera and Foreground UI Camera. It's still all very confusing and I can't find any documentation aside from the API reference which doesn't really explain anything.
     
  6. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    Last edited: May 16, 2020
  7. Pimpace

    Pimpace

    Joined:
    Sep 21, 2017
    Posts:
    41
    Another issue is that it wont apply on UI, as all canvas UI element are come with a transparent shader, and this urp_kawase_blur doesn't work with transparent objects. :( Anybody can show us a right direction? There is no any documentation how these things work. I'm searching a workable blur shader/shadergraph which can work with transparent UI objects over a year from now, and there is none. (URP or LWRP not built in renderer)

    I don't want anybody gives me a full working code here, but I'm lack of shader hlsl coding, or maybe I (as many others it seems) miss some options with SRP forward renderer options... also there are stencil override option, which I could find any proper docu what are those things and how it works. Is there anything to do with transparent elements (UGUI)? Or these whole approach are bed?

    Anybody can help?
     
  8. Arnage_nl

    Arnage_nl

    Joined:
    Mar 20, 2013
    Posts:
    25
    I found this thread as I was searching for a solution to this as well. I managed to find a way that worked for me, based on the URP_Kawase_Blur example posted here. So I'll share it in case it is useful for others as well:

    https://github.com/ArneBezuijen/urp_kawase_UI_blur

    I made it easier to work with on UIs. You only have to switch the material of a UI element to give it a blurred background. Otherwise it should match all the features of a normal Unity UI element. This approach also allows for all scene elements to be blurred and as such can include transparent objects.

    It however does not support blurring of other UI layers yet. If you don't care about transparent objects this can be achieved though: switch the render feature itself to before transparency and using two canvases. One in the default overlay mode for the non-blurred elements and one in the in-world mode for the blurred elements underneath. (If you need both blurred UI and transparent object to show up it'll become significantly harder though)
     
  9. dionen

    dionen

    Joined:
    Feb 10, 2020
    Posts:
    1
    Amazing!

    Is it possible to acess the RenderFeatures via script? For example, In case I want to animate it to gradually blur (increase value of blurPasses in runtime), is it possible? Thanks!
     
  10. Arnage_nl

    Arnage_nl

    Joined:
    Mar 20, 2013
    Posts:
    25
    Haven't had the need to do that yet, so I'm not sure, though I expect that should be possible.

    One limitation that will be there though is that the way the blurring is implemented, means that blur size scales in integer steps, so you'll either have to animate it pretty fast to not make that obvious or you might see steps in the animation progress.
     
  11. Pimpace

    Pimpace

    Joined:
    Sep 21, 2017
    Posts:
    41
    No. This is not a solution.

    upload_2020-7-7_14-0-23.png
    upload_2020-7-7_14-0-38.png

    We can see that the blur shader and forward renderer script will not allow to show transparent objects (alpha-channel).

    Not only behind UI element (this is a UI panel with a "Behind Text") but any transparent game object. (blue transparent cube).
    This shader and SRP script will get through only opaque pixels. So in this terms of subject, it's useless. I'm sorry.

    However, as I said, a more expert programmer or Unity dev help needed!
    How can we alter this shader to allow to show transparent objects?
     
  12. Arnage_nl

    Arnage_nl

    Joined:
    Mar 20, 2013
    Posts:
    25
    It seems like you just looked at the original Kawase Blur example instead of my edited version. The whole point of those edits was to support the changes you are asking for. Here's a recreation of your example to show this:

    upload_2020-7-11_21-31-39.png

    PS. I wasn't sure to reply as your message was unnecessarily rude to strangers who are trying to help you without asking something in return.
     
  13. grossing_games

    grossing_games

    Joined:
    Feb 14, 2018
    Posts:
    5
    Thanks for sharing!

    Is there any way to reproduce such effect with stacked cameras (one rendering scene and another one UI)?

    At this moment blur works only for elements rendered by main camera (i.e. scene + screen space UI).

    I guess I need to combine image from main camera and UI camera before passing it to the blur shader, but I couldn’t find where to do that.
     
    EyasSH likes this.
  14. Gandarufu

    Gandarufu

    Joined:
    Nov 10, 2014
    Posts:
    22
    @Arnage_nl Thanks a bunch for making this work with transparent objects, I've been trying to wrap my head around this for some time now. Do you know of a solution that would work on world space 3D objects, like a simple plane?
     
  15. Arnage_nl

    Arnage_nl

    Joined:
    Mar 20, 2013
    Posts:
    25
    That should work, assuming your UI is rendered in screenspace on your second camera. Overlay UI is always rendered on top and can only read the blur texture and not influence it. See below for an example of using stacked camera's with this effect. Can you elaborate on your specific setup? (Also sorry for the late reply, I missed this message and only noticed it due to Gandarufu's reply)

    The main problem is the limited control Renderer Features give over the rendering order. You can either activate it before translucency and thus miss out on anything transparent or after, but then the object that you want to render with is is already rendered so it can't access a rendertarget that isn't there yet. Ideally Unity would make this order more granular as it is in materials, but I guess that is a limitation of the way they implemented them.

    The only solution that I know of is to use camera stacking now that that is available in URP. A second camera can render a 3D object that samples the blur texture form the base camera. Note however that, as this is an overlay camera, these objects don't occlude behind objects rendered by the base camera. An advantage of this approach is that it also allows multiple layers of blurring, allowing you to put another blur layer on the overlay camera.

    Here's an example of this: The third cube is rendered with an overlay camera and blurs everything rendered by the base camera (including screenspace UI) and it is itself blurred again by the second blur pass on the overlay camera to get the blurred background for the final UI rendering.

    upload_2020-9-26_19-43-28.png

    Note: to do this you have to upgrade the project to 2019.4 as the branch I posted was made with 2019.3 which did not yet support camera stacking.
     
    Gandarufu likes this.
  16. Gandarufu

    Gandarufu

    Joined:
    Nov 10, 2014
    Posts:
    22
    Hi @Arnage_nl
    Thanks a bunch for your input on this :) That sounds exactly like what I'm looking for. I have an overlay camera that renders objects that are being examined. I was looking for a way to blur the entire screen in the background with a simple plane (also including transparent objects).
    Now, your screenshot proves that it's possible. I only need to figure the setup out. Is there any way you could include your 3 cube scene in your repository, if you have a minute?
    I'd appreciate it very much! Thanks a lot for putting so much effort into this common problem a lot of people seem to have.

    Edit: Never mind, I figured it out :) Hooray!! You're a lifesaver!
     
    Last edited: Sep 27, 2020
  17. Arnage_nl

    Arnage_nl

    Joined:
    Mar 20, 2013
    Posts:
    25
    Just saw your edit after I put it on Github :)

    Anyway in case it's useful for others too: I placed it on a separate branch (called stackedcameras) as it needed the version bump to 2019.4.
     
    Gandarufu likes this.
  18. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    286
    This works great!
     
  19. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,377
    This is one good looking blur. Now for the performance: is this bluring the entire frame and putting the entire frame inside a global texture?
    upload_2021-3-30_1-33-47.png
    Or, when used in UI, does it only blur the portion that's covered by the blur UI?
     
  20. revolute

    revolute

    Joined:
    Jul 28, 2014
    Posts:
    34
    Judging from the kawase blur render feature, it does a full screen blur and the UIBlur shader just samples _blurTexture made from kawase blur. So, nope.

    Arguably, performance would be poor if only a small part uses blur, very good if there a multiple ui components that uses blur. Traditional grabpass blur method grabs texture and blurs it per item which allows fine tuned blurs that can differ per item but at a cost.

    It already has built in downsample option so downsizing it to 1/4 and running 2 passes should be performant. ( honestly downsampling and upsampling is blur itself, just not as good ).
     
    laurentlavigne likes this.
  21. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,377
    I cranked up the downsample range to 16 and it's AWESOME!
    event on switch
     
    Reanimate_L and RogDolos like this.
  22. ridlr

    ridlr

    Joined:
    Mar 4, 2020
    Posts:
    25
    Is there any way to make this work with the 2D renderer? It doesn't seem like it supports renderer features at the moment.
     
  23. peterbay

    peterbay

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    49
    It should be supported in Unity 2021.2 with URP 12, which is in beta at the moment :)
     
  24. MagpieStudios

    MagpieStudios

    Joined:
    Jun 30, 2018
    Posts:
    17
    I'm getting an error in URP 11 in the KawaseBlur.cs script. It says:

    The name 'CommandBufferPool' does not exist in the current context


    Does anyone know how to fix this?
     
  25. Razshal

    Razshal

    Joined:
    Sep 29, 2016
    Posts:
    1
    Are you using Assembly Definiton assets in your project ?
    If it is your case, you might need to add this definiton reference in your assembly :
    Unity.RenderPipelines.Core.Runtime
     
  26. rocket5tim

    rocket5tim

    Joined:
    May 19, 2009
    Posts:
    237
    Thanks for this @Arnage_nl! Works great with ARFoundation to blur out the AR Camera when UI menus are visible.
     
  27. cakeu

    cakeu

    Joined:
    Nov 12, 2020
    Posts:
    1
    Hey! I've switched over to 2022.1.0b2 and all of a sudden i'm getting this error:


    You can only call cameraColorTarget inside the scope of a ScriptableRenderPass. Otherwise the pipeline camera target texture might have not been created or might have already been disposed.
    UnityEngine.Rendering.Universal.ScriptableRenderer:get_cameraColorTarget ()
    KawaseBlur:AddRenderPasses (UnityEngine.Rendering.Universal.ScriptableRenderer,UnityEngine.Rendering.Universal.RenderingData&) (at Assets/Resources/Assets/KawaseBlur/KawaseBlur.cs:126)
    UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)


    sebastianheim's implementation worked just fine on 2021 but now this error keeps getting spewed out, even when i switch to ArneBezuijen's implementation. I've tried changing "var src = renderer.cameraColorTarget;" to "var src = renderer.cameraColorTargetHandle;" but this error keeps appearing. What gives?
     
  28. revolute

    revolute

    Joined:
    Jul 28, 2014
    Posts:
    34
    Unity changed it. You can't use
    ScriptableRenderer.cameraColorTarget
    or
    ScriptableRenderer.cameraDepth
    at
    ScriptableRendererFeature.AddRenderPasses
    anymore. Instead, use
    ScriptableRenderPass.ConfigureInput
    and
    ScriptableRenderPass.colorAttachment 
    ScriptableRenderPass.depthAttachment
    .
     
unityunity