Anamorphic bloom is for sure the most cyberpunk aesthetic there is. I wanted to use it as a use case for learning how to create post process materials for Unity URP. This post explains the process.
I was browsing audio / music reference for the game and happened upon some cyberpunk ambient music on YouTube. These videos had massive anamorphic flaring and it looked pretty cool in a cyberpunk setting. I figured adding a similar effect to Echoes of Somewhere would not be a big task and it might make the game image look cooler/more genre appropriate as well!
After a quick google, I happened upon this tutorial:
The tutorial did not outline the process for creating bloom effect for the Universal Render Pipeline (URP), but I figures it would explain the basics of how post process materials generally work so I could use it to get started. And I was right. There were some differences with some nodes and post process materials were applied on the image as rented pipeline features, not volumes. But the general logic was the same.
Creating the custom anamorphic bloom post process material
Armed with the very helpful YouTube tutorial and the Unity manual, I set to work!
First, I created a full screen shader graph. This graph is used to make materials that can be injected in the URP render pipeline.
Using the Post Process Bloom tutorial, I managed to get a basic bloom shader graph going very quick. I stopped following the tutorial quite quick though, as I already had a handle of the basics.
For the screen sampling, I did not follow the tutorial exactly. The tutorial seems to be built to be pixel dependent, meaning it will produce a different blur scale based on screen resolution. I wanted my bloom to be uniform across all resolutions, so I made mine resolution independent.
The screen sampling subgraph also handles the threshold calculations.
I am not sure of the perf impact of the screen sample function, so I only dared to loop it 16 times. I thought it was the minimum to get the bloom wide enough while not looking too low quality. The more samples I get, the smoother I can make the bloom.
The shader has some controls for the look of the blur:
Brightness, threshold and width.
Brightness, obviously, controls how intense the bloom is, threshold controls how bright an area must be for it to flare and with controls how wide the effect will be.
(I already fixed the “treshold” typo, but can’t be bothered to capture new images)
In order for the effect to be rendered on the game image, an additional URP renderer feature “Full Screen Pass Renderer Feature” needs to be added. This feature can be used to render any custom render pass material on the image. You can use the shader graph to do almost any kind of effect on the image! Like pixelation, distortions, b&w, sepia, blooms, even crazy custom UI elements.
Comparisons of the custom screen space bloom effect:
I am a big fan of how the bloom further plants the 3D elements into the painting. Further making the black levels match.
Setting up the SRP lens flare
The SRP lens flare in unity 2022 (as of now) is broken. When you create a new SRP flare and select it, Unity editor spits out a ton of errors. I wish unity will fix this asap, but before they do, In order to get any lens flares to your Ump project, you can use the example set.
To get the pre-built flares, you need to install the URP package sample from the Package Manager. This package includes a bunch of URP examples, but the one you need is in the Lens Flares -folder.
The flares work and render correctly, but selecting any of them produces an error. You can still use the flares in the scene without issues. (in Unity 2023.1.11f1 flare editing works just fine!).
ArgumentException: Incorrect number of arguments supplied for call to method 'UnityEditor.GenericMenu FillPropertyContextMenu(UnityEditor.SerializedProperty, UnityEditor.SerializedProperty, UnityEditor.GenericMenu, UnityEngine.UIElements.VisualElement)'
Parameter name: method
System.Dynamic.Utils.ExpressionUtils.ValidateArgumentCount (System.Reflection.MethodBase method, System.Linq.Expressions.ExpressionType nodeKind, System.Int32 count, System.Reflection.ParameterInfo pis) (at <5e8e062dfaf44f8db343211dde07639b>:0)
System.Linq.Expressions.Expression.ValidateArgumentCount (System.Reflection.MethodBase method, System.Linq.Expressions.ExpressionType nodeKind, System.Int32 count, System.Reflection.ParameterInfo pis) (at <5e8e062dfaf44f8db343211dde07639b>:0)
System.Linq.Expressions.Expression.Call (System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2) (at <5e8e062dfaf44f8db343211dde07639b>:0)
UnityEditor.Rendering.LensFlareDataSRPEditor..cctor () (at ./Library/PackageCachefirstname.lastname@example.org/Editor/PostProcessing/LensFlareDataSRPEditor.cs:114)
Rethrow as TypeInitializationException: The type initializer for 'UnityEditor.Rendering.LensFlareDataSRPEditor' threw an exception.
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass72_0.<CreateInspectorElementUsingIMGUI>b__0 () (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:713)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:190)
I ended up using different types of flares in different scenes. I know it is not realistic, but I decided to go with feel, instead of “realism”. For some scenes I used the classic sci-fi anamorphic flares, but for others I used the flares as more of god-rays / large bloom elements. I only upgraded the project to Unity 2023 today, so I have not yet looked into editing these flares, but I expect it to be very similar to any other flare systems.
Some screenshots with the SRP lens flares:
I think the really heavy handed flares work well in this cyberpunk / sci-fi setting. In any other genre I would not necessarily go as hard on them. But this aesthetic seems to really ask for them. Also, the music of the game fits the bloomy / flared look really really well.