1
\$\begingroup\$

I'm trying to fake a DOF effect for Sprites by using 2 cameras, one for the sharp objects, one for the blurred ones. I have set up the layers like Blur and Sharp accordingly.

So I have these 2 cameras, and I use Unity's Blur (optimized) script to blur things, and I have this script on only one camera, the one that is responsible for the blurred render.

I have the cameras like:

Cam 1:

  • Clear flags: Don't clear (this is the main, sharp cam)
  • Culling mask: sharp layer
  • has no blur effect (or any other post proc effect).

Cam 2:

  • Clear flags: don't clear (this is the blur cam)
  • culling mask: blur
  • Has Blur (optimized).

Now, if this blur cam is on the back, meaning its depth is LESS than the main cam's depth, I have a sharp player ground and a blurry background. However, I need a blurry foreground too that should be on top of the player ground.

The issue starts when I set the blur camera's depth higher than the main cam's. In this case, everything gets blurred, no matter that the main cam has no blur effect on it.

Question is, how to set this up so only the desired layers get the blur?

\$\endgroup\$
13
  • 2
    \$\begingroup\$ Remember, blur is a post effect, meaning it comes at the end of a rendering pass. It's not blurring the objects as they're rasterized, it's compositing the full rendered image then blurring that image. That means you'll need to do one of three things: 1) pre-blur your soft sprites' textures, if they stay in their blurred layer. 2) blur each sprite in its shader (possibly be interpolating with a blurred texture as in 1) or 3) composite your foreground objects onto a RenderTexture with a transparent background, blur that, then draw the blurred result over the rest of the scene. \$\endgroup\$
    – DMGregory
    Jul 16, 2017 at 21:08
  • \$\begingroup\$ @DMGregory Thank you for your answer. The most chance with my current skillset I have in on the RenderTexture solution. Is that too big a performance hit on mobile in terms of memory of cpu? And if not, where to begin looking for it (besides Google "Unity RenderTexture")? \$\endgroup\$
    – agiro
    Jul 17, 2017 at 3:58
  • 1
    \$\begingroup\$ If that sounds like a good direction to you then I'll write something up for you. In general, composing multiple render targets is quite expensive on mobile — they're often memory bandwidth bound, so any time they have to write a frame buffer out to shared RAM then read it back later in the frame they pay for it, compared to drawing the whole result beginning-to-end for each tile in one go. TBD whether this is too much cost for your particular application & target hardware, though using a reduced target size for blurry areas might help. \$\endgroup\$
    – DMGregory
    Jul 17, 2017 at 4:03
  • \$\begingroup\$ Currently I only plan to blur the foreground and wish to do so by using some pre-blurred sprites. Do you think these sprites are a better idea for this scenario in terms of memory hit? By the way the whole reason I mess with this RenderTexture and compositing is to save on sprite memory. \$\endgroup\$
    – agiro
    Jul 17, 2017 at 4:14
  • 1
    \$\begingroup\$ We're veering into discussion and it's 2AM here. ;) Hit me up on Chat or on Twitter (@D_M_Gregory) if you want to talk about it further. Otherwise, it sounds like you're already well on your way to an answer you can post. :) \$\endgroup\$
    – DMGregory
    Jul 17, 2017 at 6:31

1 Answer 1

2
\$\begingroup\$

With the help of DMGregory there is some neat workaround to basically fake depth of field for sprites. The reason we can't just blur the foreground cam is that these post-processing effects take the final image and work the magic on them.

There are of course more than one ways to do so. One is to sort of pre-blur your sprites in an external 2D app (GIMP or PS for example) and export it to Unity, that way you have a "static" sprite that doesn't need much calculation other than a simple sprite as it is.

This however forbids you from a lot of options like animating the blur, making it more dynamic, reduce the blur if you are unsatisfied and so on.

The other is to use RenderTextures. To do so, you max want to create one in the inspector Right click > Create > RenderTexture and set it up so it suits your needs. I kept it low res as blurred images don't really need to be crisp.

Once you have it, create another camera and set up its layers so it renders only the foreground. In the meantime your main cam should exclude the foreground. Make this BlurCam a child of your MainCam so it follows it. Its depth shall be higher than your MainCam's.

Unity has some scripts, like Blur (optimized) to get you a nice result fast enough. Put that on your BlurCam. After that, assign your RenderTexture as Target Texture for the BlurCam. Set BlurCam's clear flags Solid Color and make its alpha 0.

Drop a mesh plane on the canvas and make it a child of the BlurCam (so it follows it).

Assign a transparent unlit shader (or whatever you wish, it worked nice with my sprites) to that plane and make texture your RenderTexture.

After that, if you placed the plane right, you basically see all your "Foreground" layer sprites blurred. You just have to toss around those sprites to the scene, the blur happens rendertime.

Bear in mind though, that this RenderTexture method, if abused, can propose a meaningful performance hit, especially for mobile as it is a weaker hardware. Always keep an eye on your profiler before setting up these.

\$\endgroup\$
2
  • \$\begingroup\$ You don't need to add "Solved" to the question title. Instead, once the waiting period is up, you should mark your answer as "Accepted" - this is how the system sorts solved questions from those still needing attention. \$\endgroup\$
    – DMGregory
    Jul 19, 2017 at 22:10
  • \$\begingroup\$ Yes and I did just that now, thanks for pointing it out. I wrote the "solved" stuff because the method is an answer for another feature too (DOF for sprites) that was readily requested on forums, but it isn't the original question. This way others who search for "Unity sprite DOF" may find this. \$\endgroup\$
    – agiro
    Jul 20, 2017 at 6:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .