Colibri AA · Anti-aliasing for Unity URP
Documentation
Colibri AA: anti-aliasing for Unity URP
Three anti-aliasing modes in one renderer feature, one mode at a time:
- CF (Colibri Flash): morphological anti-aliasing of the frame, without MSAA.
- C2x: Colibri Flash on top of MSAA 2x, or MSAA 4x with MSAA 4x in Advanced.
- CT2x (Colibri Temporal): two frames with a sub-pixel camera offset blended on top of MSAA 2x. It runs on the main camera of the renderer; Every Camera in Advanced runs it on every camera of the renderer, each with its own history. Frame Shift in Main sets how far apart the two frames are: smaller is sharper with more shimmer in motion, larger is softer and steadier, closer to TAA.
What's new in 1.1
- Frame Shift for CT2x in Main: how far apart the two frames are, from 0.25 to 1.75. Default 1, no performance cost.
- In the editor, every
ColibriAA.Usecall that changes something writes one line to the Console: what changed and which method called it. - C2x and CT2x on a camera without the MSAA they are built on give one warning with the reason. The Colibri AA window shows it too, and Turn on becomes available again.
- The example menu below no longer changes the camera on the Colibri AA items.
- The Debug Mode report keeps a history of mode and MSAA changes.
- Restore stock keeps the upscaler chosen before Turn on when the project moves to Unity 6.7.
- Unity 6.6 and newer: no analyzer warnings about static fields when Play Mode starts without a domain reload.
Requirements
- Unity 6.0 or newer with the Universal Render Pipeline 17.0.4 or newer, rendering through the Render Graph.
- Compute shaders: Metal, Direct3D 11, Direct3D 12 or Vulkan.
Tested on
Three states, and they mean different things. Measured — run and timed by us. Runs — run and looked at, without numbers. Not tested — we have no such device, and the package makes no promise about it.
| state | |
|---|---|
| Graphics API | Direct3D 12 — measured · Direct3D 11, Vulkan, Metal — runs |
| Unity | 6000.0 · 6000.3 · 6000.6 · 6000.7 — runs; the numbers in the store listing come from 6000.7 |
| URP | 17.0 through 17.7 — runs. The upscaler framework of 17.3 and newer is read through reflection; on 17.0 the older field is used instead |
| GPU | NVIDIA RTX 4070 Laptop — measured · Apple M2 Pro — runs |
| Rendering paths | Forward, Forward+, Deferred, Deferred+, 2D — run; Deferred has no MSAA in URP, see Limitations |
| Colour space | Linear and Gamma — run |
| VR | not supported yet |
| Not tested at all | consoles · Nintendo Switch · WebGPU · WebGL · hardware dynamic resolution |
Installation
- Install the package. The Colibri AA tab opens next to the Inspector.
- Press Turn on. Colibri AA is added to every renderer of the project's URP Assets, and their MSAA is set for the mode.
- Choose the mode: CF, C2x or CT2x. The settings of the mode are under Main and Advanced; hover a setting for what it does. Reset to Defaults under each mode puts only that mode back to the factory values.
The window is under Window > Rendering > Colibri AA. The Colibri AA entry in a renderer asset has a button that opens it too.
Turn on sets the MSAA the mode is built on, and while Colibri AA is on, a mode chosen in the window sets it too. Restore stock puts the MSAA values back and removes the Colibri AA lines Turn on added. If a renderer loses its line, the line is switched off, or something lowers the MSAA of a URP Asset below the mode — a script, a quality change, a hand edit — Turn on becomes available again and puts it right, and the window says what it found.
Turn on also sets plain Bilinear scaling in the URP Assets that use an upscaler with its own anti-aliasing or sharpening (STP, FSR, MetalFX, DLSS), and a Render Scale of 1 where the upscaler rendered below it; Restore stock brings both back. While Colibri AA renders a camera, the camera's own anti-aliasing (FXAA, SMAA, TAA) is off for that frame; the camera component keeps its setting.
Anti-aliasing menu in your game
Most games let the player pick anti-aliasing in the settings. Colibri AA takes one line per menu item:
using Make1iveStudio.Colibri;
ColibriAA.Use(ColibriChoice.CF); // Colibri Flash
ColibriAA.Use(ColibriChoice.CT2x); // MSAA 2x and two frames
ColibriAA.Use(ColibriChoice.Off); // Colibri AA off, the camera's own anti-aliasing works
The call does the three things a hand-written menu has to remember:
- It sets every Colibri AA line in the project. A project with a URP Asset per quality level has a line in each, so a quality change made later in the same menu keeps the choice.
- It sets the MSAA the mode is built on: C2x and CT2x need MSAA 2x, CF and Ultra need none.
- With Off the lines stay in the renderers and do nothing, and the camera's own FXAA, SMAA or TAA works as usual. Colibri AA turns the camera's anti-aliasing off only for the frames it anti-aliases itself, and never changes the camera component.
The choices are Off, CF, C2x, CT2x and Ultra. Ultra is CT2x with Colibri Flash in place of MSAA: it brings the two-frame blend to a project or a camera that renders without MSAA.
Each menu item in code
| Menu item | Code |
|---|---|
| Off | ColibriAA.Use(ColibriChoice.Off); and the camera's anti-aliasing set to None |
| FXAA, SMAA, TAA | ColibriAA.Use(ColibriChoice.Off); and the camera set to that anti-aliasing |
| MSAA 4x | ColibriAA.Use(ColibriChoice.Off, msaaWhenOff: 4); and the camera's anti-aliasing set to None |
| CF, C2x, CT2x, Ultra | ColibriAA.Use(ColibriChoice.CF); and so on; nothing to set on the camera |
Off sets MSAA to 1x unless you pass another count, because FXAA, SMAA and TAA run without MSAA.
A complete menu
Put this script on any object, give it the main camera, fill a dropdown with the Items below in the same order, and hook Pick to the dropdown's On Value Changed.
using Make1iveStudio.Colibri;
using UnityEngine;
using UnityEngine.Rendering.Universal;
public class AntiAliasingMenu : MonoBehaviour
{
public Camera mainCamera;
public static readonly string[] Items = { "Off", "FXAA", "SMAA", "TAA", "MSAA 4x", "CF", "CT2x" };
public void Pick(int item)
{
var camera = mainCamera.GetUniversalAdditionalCameraData();
switch (Items[item])
{
case "Off": ColibriAA.Use(ColibriChoice.Off); camera.antialiasing = AntialiasingMode.None; break;
case "FXAA": ColibriAA.Use(ColibriChoice.Off); camera.antialiasing = AntialiasingMode.FastApproximateAntialiasing; break;
case "SMAA": ColibriAA.Use(ColibriChoice.Off); camera.antialiasing = AntialiasingMode.SubpixelMorphologicalAntiAliasing; break;
case "TAA": ColibriAA.Use(ColibriChoice.Off); camera.antialiasing = AntialiasingMode.TemporalAntiAliasing; break;
case "MSAA 4x": ColibriAA.Use(ColibriChoice.Off, msaaWhenOff: 4); camera.antialiasing = AntialiasingMode.None; break;
// The Colibri AA modes leave the camera as it is: Colibri AA turns its anti-aliasing off only for the frames it renders.
case "CF": ColibriAA.Use(ColibriChoice.CF); break;
case "CT2x": ColibriAA.Use(ColibriChoice.CT2x); break;
}
}
}
Good to know
ColibriAA.Currenttells which choice the game renders with — the line of the renderer the main camera draws with, or of the default renderer when there is no main camera — to show it as selected when the menu opens.- Until the first call the lines run as Turn on left them, in the mode chosen in the window.
- In Play Mode in the editor whatever
Usechanges is put back when Play Mode ends, so trying the menu leaves the project as it was. Called outside Play Mode, from an editor script, the change stays. - In the editor every
Usecall that changes something writes one line to the console: what it changed and which method of the game called it. A menu that applies a saved choice when the game starts shows up there. - C2x or CT2x on a camera without the MSAA they are built on writes one warning in the editor, naming the cause: the camera's Allow MSAA, its Render Texture, or the MSAA of the URP Asset.
- C2x and CT2x need a camera with Allow MSAA on. If your camera has it off, offer CF and Ultra: they need no MSAA.
ColibriAA.Available(choice, camera)answers whether a menu item does what its name says here, andColibriAA.Unavailable(choice, camera)gives the reason in one sentence, or an empty string. A renderer without a Colibri AA line, a camera with Allow MSAA off, a Render Texture without multisampling, a Deferred renderer, an overlay camera, XR, a Pixel Perfect camera the line leaves alone, a temporal upscaler on the camera, CT2x on a camera that is not the main one while Every Camera is off, Render Graph compatibility mode, and a device that cannot run the Colibri Flash kernels or the CT2x shader are what it catches. Asking changes nothing in the project or the scene. Hide such an item, or grey it out and show the reason — without it the player picks C2x and gets CF.
Camera cuts
CT2x and Ultra blend each frame with the one before it. On a cut — a new shot in a cutscene, a respawn, a teleport — tell the camera for the first frame of the new shot, with the flag URP's own TAA reads:
mainCamera.GetUniversalAdditionalCameraData().resetHistory = true;
That frame is drawn without the previous one, and URP clears the flag by itself. Without it, the first frame of the new shot still carries the old one, blended in.
Removing the package
Press Restore stock before you remove the package. Otherwise the renderers keep an entry whose script is gone, the URP Assets keep the MSAA and scaling of the mode, and materials with the Colibri AA/Lit shader have no shader to render with.
Anti-Shimmer
Small highlights on curved and bumpy surfaces flicker in motion. Anti-Shimmer (Main of C2x and CT2x) spreads such highlights slightly before they can flicker. The filter works inside the surface shader, before lighting:
- Materials: select the Colibri AA/Lit shader. It is the URP Lit shader with the filter inside, built by the package from the Lit shader of the installed URP, so it keeps every Lit setting and follows URP updates.
- Hand-written shader: in the lit passes,
#pragma multi_compile_fragment _ COLIBRI_SPECULAR_AAand#include "Packages/com.make1ive.colibri/ShaderLibrary/ColibriSpecularAA.hlsl", then in the fragment stage, before lighting:smoothness = ColibriSpecularAA(smoothness, geometricNormalWS); - Shader Graph: a Boolean Keyword
COLIBRI_SPECULAR_AA(Multi Compile, Global) and a Custom Function node withColibriSpecularAA.hlslas the source andColibriSpecularAAas the name; inputs Smoothness (Float) and NormalWS (Vector 3, world-space normal), output Out into Smoothness.
Colibri AA enables the filter only for the cameras it renders while Anti-Shimmer is on. Otherwise the shaders are compiled without it, and it costs nothing.
Upscalers
Turn on puts the URP Assets that use an upscaler with its own anti-aliasing or sharpening (STP, FSR, MetalFX, DLSS) back to plain Bilinear scaling, and Restore stock brings the upscaler back. Where such an asset rendered below full size, Turn on also sets its Render Scale to 1, because plain scaling would blur the smaller frame. The frame then costs more: a Render Scale of 0.75 drew 0.56 of the pixels, and full size draws 1.78 times as many. Restore stock puts the Render Scale back as well.
If the game lets the player pick an upscaler at runtime, Colibri AA steps aside by itself: on a camera anti-aliased by a temporal upscaler — STP, DLSS, FSR 2 and 3, MetalFX — the line does nothing and says so once in the console. Switch Colibri AA off while such an upscaler is on, and give the player's choice back when the upscaler is turned off:
ColibriAA.Use(upscalerOn ? ColibriChoice.Off : playerChoice);
FSR 1.0 does not anti-alias the frame: Colibri AA keeps working with it.
Limitations
- CT2x without Anti-Ghosting takes motion from the camera and depth only, which costs less; fast moving objects can leave a trail. Anti-Ghosting gives them their own motion vectors and removes the trail at the cost of drawing them once more. Do not turn it on just in case: the trail is often invisible to the eye, and we had to build dedicated scenes just to see it.
- The camera renders into an intermediate texture while Colibri AA works on it. In a project where URP would otherwise draw straight to the screen — post-processing, HDR, MSAA, the depth texture and the opaque texture all off — this adds that texture and a copy to the screen on top of the anti-aliasing itself. Measured on the RTX 4070 Laptop with Direct3D 12 at 2560×1440, the addition could not be told apart from the measurement noise of about 0.01 ms per frame.
- A frame without HDR is an 8-bit sRGB texture in the Linear colour space, and on Direct3D 12, Direct3D 11 and Vulkan a compute shader cannot write it. Colibri Flash then works in a texture of its own and copies the frame in first: 0.05 ms per frame at 2560×1440 on the same machine. Metal writes such a frame directly.
- Deferred and Deferred+ rendering paths have no MSAA in URP: C2x runs as CF, and CT2x blends two frames without MSAA.
- MSAA is often off in a URP project by its author's choice, and then C2x and CT2x run without it. A camera with Allow MSAA off gets no multisampling whatever the URP Asset holds. Projects built around screen-space effects — ambient occlusion, fog, decals — commonly ship that way, because those effects read the depth texture and with MSAA the pipeline has to produce it by a pass of its own. Unity's own Fantasy Kingdom sample is one: every quality level ships MSAA 1 and the camera has Allow MSAA off. CF and Ultra Performance need no MSAA and run in any of these projects; for C2x and CT2x the camera has to allow it. The window says so when it happens.
- The 2D renderer draws straight to the screen unless something asks it for an intermediate texture, so the line asks for one while it works. CF and C2x anti-alias sprites there. CT2x blends two frames without motion vectors, which the 2D renderer never draws: moving sprites leave a trail, and with Anti-Ghosting on CT2x does not run at all there and says so once in the console.
- Pixel Perfect Camera: a camera with that component is left alone, since the staircase of pixel art is meant to be seen. The Pixel Perfect Camera setting, shown for a 2D renderer, anti-aliases it anyway.
- Overlay cameras of a camera stack are not anti-aliased by Colibri Flash: they draw on top of the frame their base camera has already anti-aliased. Material previews and reflection probes are not anti-aliased either.
- Colibri Flash builds its edge lists with atomic operations of compute shaders. Where the device has no wave intrinsics, Colibri AA checks once at startup that these operations work; if they do nothing, Colibri Flash turns itself off with one warning instead of leaving a black frame, and CT2x on MSAA keeps working.
- XR and stereo rendering are not supported: XR cameras are rendered without Colibri AA.
- Render Graph compatibility mode of Unity 6.0 to 6.3 is not supported: Colibri AA stays off there, logs one warning, and the window says where to turn the mode off.
- On a URP version whose internals have moved, Colibri AA falls back rather than fails: it copies the frame where it would otherwise write into the camera colour directly, and builds its copy of the Lit shader without Anti-Shimmer if URP no longer calls the function the filter replaces. Both leave a message in the console, and Debug Mode names the path that was taken. The frame is correct in either case; the fallback costs one full-frame copy.
Debug Mode
Turn on Debug Mode at the bottom of the settings when something looks wrong, and reproduce the problem. Colibri AA rewrites a report every two seconds while a camera renders with it: the device, the URP Asset and renderers, the Colibri AA settings, every camera and what Colibri AA did for it, the pass counters, automatic checks, and the errors logged meanwhile. Show Report opens its folder: Logs/ColibriAA/ColibriAA-Report.txt in the project, or ColibriAA-Report.txt in Application.persistentDataPath in a player. Send the file with your problem report. Debug Mode changes nothing in the image; turn it off before shipping.
License
Colibri AA is licensed under the Unity Asset Store EULA, see LICENSE. It includes third-party code under its own licenses, in THIRD_PARTY_LICENSES: a modified version of Intel's CMAA2 under the Apache License 2.0, code derived from Alexander Malyutin's Unity URP port of CMAA2 under the MIT License, and color packing code from Microsoft MiniEngine under the MIT License.
Setup guide
Colibri AA — setup in four steps
- Import the package into a Unity 6 project that uses the Universal Render Pipeline.
- Open Window ▸ Rendering ▸ Colibri AA and press Turn on. The window adds the render feature to every URP renderer in the project, sets the MSAA level the chosen mode needs, and keeps a backup of what it changed.
- Pick a mode: CF, C2x, CT2x or CT2x Ultra. Everything else stays on Auto — the pass reads the colour range, post-processing, MSAA, engine version and graphics API by itself.
- From game code, switch modes with one call:
Make1iveStudio.Colibri.ColibriAA.Use(Make1iveStudio.Colibri.ColibriChoice.CF);
Restore stock puts the project back exactly as it was: the feature rows are removed and the MSAA levels return to the saved values.
Support: write to the studio at make1ive.com/colibri-aa with your Unity version and graphics API in the first line.