What we have here, is the result of thinking “surely we can do better than that?” when looking at the Screen Overlay effect from Unity’s Standard Assets. But it wasn’t me who thought it.
A nice group of developers, making a nice little game wanted a full screen gradient effect on Mobile devices and weren’t happy with the performance they were getting on lower end devices out of the built-in effects.
So this is where I come in, and as always it’s never as simple as you’d hope it would be. The Unity built-in Overlay affects uses the OnRenderImage callback, an immediate performance hog, especially for such a simple effect. Using this function implicitly changes how the camera renders the scene, it no longer simply presents the result to the screen, it creates a Render Texture the same size as the screen, renders the image into it and passes it through to your effect. If you have two or more effects, it will create a second Render Texture and alternate between them as source and destination textures in the call back.
Inside of this callback you are expected to, at some point and in some way, render a version of the scene to the destination texture, likely using the source texture as an input. If you don’t fill the destination texture with anything, then nothing is presented to the screen, it’s as simple as that.
It’s a simple and powerful system to use, but our problem is a nail and what Unity provides us with is a sledgehammer. It’s capable of everything from Depth Of Field to Edge Detection. All we want is to render a texture over the screen.
We’re now (hopefully) all thinking something along the lines of “Ok, just render a quad to the screen, problem solved” and you would be absolutely correct. But how? The person interacting with this effect would like it to be as simple to use as possible, similar to the Unity effect.
They don’t want to have to add a quad as a child of the Main Camera, they don’t want to maybe set up an orthographic camera off to one side, they don’t want to add a full screen UI element, or any other way you can think of to manually set this effect up. They want a script you can drag onto a camera, maybe set a couple of variables and you’re off. So that’s exactly what I made.
What we’ve ended up with is an overlay effect which pretends to work in exactly the same way as the built-in Unity Overlay effect. It has 9 built-in blend modes (inspired by Photoshop), it manages the lifetime of it’s own quad and material, updates dynamically in the editor (while not playing), does not use render textures, and most importantly runs in 1/3rd the runtime cost of the standard effect.