Translucent Editor Windows in Unity3D

With iOS, OS X, Windows and the web all going blurry and translucent I spent some time looking into how to recreate the effect in the Unity3D editor.

Jim Fleming
3 min readMay 15, 2015
Spotlight, OS X Yosemite

Translucency is trendy and, as far as I’m aware, it’s a unique look in the Unity editor. I recently experimented with faux translucency while working on Haste, a Unity editor extension, and it was fun to figure out how it could be done.

From a utility standpoint, adding translucency to modal windows is a great way to minimize the loss of context by only obscuring instead of occluding. The final effect definitely looks like translucency and uses very little resources. The downside to this technique is that the blur is static and does not update behind the window so the illusion breaks down pretty quickly if the background changes at all.

Screen-capture it

In order for translucency to work, you want to start with a screen capture taken without your modal window, ideally just before it opens. The easiest way to do this is to capture a swatch of the on-screen pixels using Unity’s internal utility function which returns an array of color values for any rectangle of pixels on the screen.

UnityEditorInternal.InternalEditorUtility.ReadScreenPixel(position, width, height);

By adding these pixel colors to a 2D texture we have the background image we needed.

The full script to build a 2D texture from these pixels can be found here: https://gist.github.com/jimfleming/dcdd481ffec122f40def

Blur it

Now that we have a starting image we need a shader to blur it nicely. I used a simple two-pass separable blur with an additional tint pass to decrease contrast. This blur is really fast, especially for small windows, and can easily handle large-radius blurs. It’s also customizable, so it’s easy to balance the tradeoffs between quality and performance.

You can find the shader used here: https://gist.github.com/jimfleming/850a5665749d2ccb055f

Magic it

Now comes the magic. We need to connect the shader to the screen-capture and we need a RenderTexture to do it. Unfortunately, without instantiating or modifying objects in the scene there’s no camera available to provide a RenderTexture. Fortunately, there’s a workaround.

The editor has access to the “active” RenderTexture which we can temporarily override during blurring then restore when we’re done. We always want to do this using a try/finally block to make sure we don’t break the main renderer. This happens very quickly and avoids instantiating things in the scene. Now that we have our RenderTexture, the script just wraps the shader with a material and uses Graphics.Blit to perform the actual blurring.

Here’s the full blur script used: https://gist.github.com/jimfleming/0f1ecf5ac4a5d6f6a9a8

var blur = new Blur(width, height);
var backgroundTexture = blur.BlurTexture(swatch);

Finalize it

Now that we’ve got our blurred swatch in hand we use the GUI API to draw the texture before drawing the rest of the window controls:

UnityEngine.GUI.DrawTexture(new Rect(0, 0, width, height), backgroundTexture);

And we’re done!

Haste opened in Unity3D. Note the translucency where the 3 cubes display through the modal window.

Conclusion

It’s subtle, but looks great. We ended up not shipping this in Haste since the background is static but overall I’m pretty happy with the effect.

If you figure out a work around, I’d love to hear from you. I tried a few hacks to get around these limitations like moving or closing and reopening the window on odd frames but Unity requires the window to close for a whole frame before grabbing the swatch which creates a flicker.

Follow me on Twitter for more experiments like this: @jimmfleming

--

--