Thursday, May 28, 2015

Unity - blur on one camera effects the other as well



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?



Answer



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.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...