Preview of URP Ground Truth Ambient Occlusion (GTAO)

We’re working on a major upgrade to URP’s Screen Space Ambient Occlusion, as part of a larger initiative to improve URP’s graphical fidelity, and we aim to ship it in Unity 6.7. Today we’re pleased to show a first version and we’d love for you to try it out and tell us what you think.

What is GTAO?

The Ground Truth Ambient Occlusion (GTAO) estimates how much of the hemisphere above each pixel is blocked by nearby geometry, by integrating horizon angles read from the depth buffer. Unlike URP’s previous ambient occlusion, it produces more physically-grounded contact shadows with less over-darkening, and it can be denoised with spatial and temporal filtering so it stays clean even at low sample counts. The existing SSAO algorithm [Alchemy] continues to be supported, so you can adopt GTAO where you want it and keep the previous look everywhere else.

Getting Started

The full guide to enabling and configuring the feature is here: URP Ambient Occlusion Guide. In short:

  1. Get the latest Alpha release (at least Unity 6000.7.0a1).

  2. (Alpha only) Add the MODERN_SSAO scripting define to your project to unhide the new options.

  3. Enable the Screen Space Ambient Occlusion Renderer Feature on your URP Renderer, as before.

  4. Add a Screen Space Ambient Occlusion override to a Volume in your scene, set Mode to GTAO, and tune it from there.

Once you’ve tried it, please help us focus our efforts by filling out this short survey: URP GTAO Ambient Occlusion -URP GTAO Ambient Occlusion - Product Experience Feedback. If you hit any bugs or anything not covered in the guide, let us know in this thread.

What’s new compared to the previous URP SSAO

  • Ground Truth Ambient Occlusion (GTAO): We have introduced a more physically-accurate algorithm alongside [Alchemy] SSAO. You can now toggle between these modes via a new dropdown, allowing for superior contact shadows. The “None” setting also enables you to bypass AO while keeping your parameters intact.
  • Volume-Based Configuration: SSAO is now integrated into the Volume system, enabling authoring and blending variations of SSAO settings within the Scene. While global Renderer Feature settings are kept for reference, the Volume overrides are now authoritative at runtime. This ensures that existing projects maintain their current look until you choose to upgrade.
  • Compute Shader Path: For enhanced fidelity, GTAO leverages compute shaders to provide granular control over step and direction counts. A raster fallback is available for broader compatibility, though the compute path is broadly supported across mobile and desktop platforms, including WebGPU and OpenGL.
  • Spatial filtering: The compute path adds selectable spatial denoisers, including Bilateral, and Box filters. These help GTAO stay clean even at low direction/step counts, and optionally at reduced resolution.
  • Temporal filtering: An optional temporal accumulation path reprojects and blends AO across frames using motion vectors, producing more stable, low-noise results during motion.

FAQ

Does GTAO replace URP’s existing SSAO?

No. The existing algorithm is kept as the SSAO mode and your current projects render exactly as before. GTAO is an additional, higher-quality option you opt into per scene.

Do I need compute shaders to use GTAO?

GTAO runs through either a raster fallback or a compute path. The compute path is recommended and is required for temporal filtering and the advanced spatial filters.

Does GTAO require motion vectors?

Only the temporal filter does - it needs motion vectors to reproject the previous frame. Spatial-only GTAO does not.

Can I still configure SSAO from the Renderer Feature?

While it is still possible to use the Renderer Feature for configuration, we keep these settings primarily as a reference or fallback to ensure existing projects maintain their current look during migration. Please be aware that these parameters remain subject to adjustment as we continue to polish the Volume-based workflow in the future.

How does GTAO affect performance?

GTAO costs a little more than SSAO. You can dial it in with quality presets, lower direction/step counts, downsampling, and your choice of spatial filter, and lean on temporal accumulation to keep quality high at a low per-frame cost.

18 Likes

Hi. There is a bug with current GTAO that it’s overdarkening other side of the model when using with double-sided materials. Example with simple plane:

1 Like

You should configure your materials to use flipped normals on the backface instead of back face normals. I’ve had to do this on clothing and such for a long time.

It’s default Lit material with Render Face set to Both. I don’t need to configure anything

does it work with single pass pc vr? (quest link)

2 Likes

What sacb0y means is that the default Lit material does not flip back face normals, therefore they will be lit the same as the front faces, so if the front face is facing a light source, the back face will also be bright. HDRP materials have option to Flip or mirror the back face normals. “Flip” means they face the exact opposite direction than on the front face, effectively inverting normal maps on back faces, whereas “Mirror”, well, mirrors the normal, so that normal maps behave exactly the same as they would on front faces.

Unfortunately, no such setting exists in the URP lit shader, but it can be implemented in shader graph.

1 Like

this sounds like a highly important thing not to be built in, do you have such a thing for us people who are crap at making something like this?

The OP image in a comparison slider:

4 Likes

I’m afraid I don’t have a complete shader with all features of the Lit shader and flipped/mirrored normals to share, but I recently posted this branchless solution for mirroring normals in shader graph: Grass normals shader graph - #5 by Sam3million

A minor issue I don’t know how to solve in the shader is that shadow artifacts can appear on backfaces if the shadow normal bias in the URP settings or the light source is too high. I have only tested this in 2022.3, not 6.x, so I don’t know if there is any difference. Also this solution will not work in older versions than 2022.x, because you could not use the “Is Front Face” node as a number before that, only as a boolean, so you had to use branching.

Edit: Here are two solutions with Branching, the first one is the same as mine above (I think I originally based it on this one), but with branching, and the second one allegedly replicates the “Flip” setting in the HDRP Lit shader, but I haven’t checked it myself: Shader graph + LWRP, can't use flipped normals?

Of course, in 2022.x and later it can easily be changed into a branchless version.

However, in many cases it can make more sense to use duplicated (and flipped) geometry instead of using a custom double-sided shader.

1 Like

For some reason I was sure that Lit has proper normals when double-sided enabled, but yeah, it doesn’t. It should be fixed in Lit shader then.

1 Like

Hello. There’s a function GTAOMultiBounce in CommonLighting.hlsl from the URP core package in 6.3LTS. Is this a totally different thing?

// ref: Practical Realtime Strategies for Accurate Indirect Occlusion
// Update ambient occlusion to colored ambient occlusion based on statitics of how light is bouncing in an object and with the albedo of the object
real3 GTAOMultiBounce(real visibility, real3 albedo)
{
    real3 a =  2.0404 * albedo - 0.3324;
    real3 b = -4.7951 * albedo + 0.6417;
    real3 c =  2.7552 * albedo + 0.6903;

    real x = visibility;
    return max(x, ((x * a + b) * x + c) * x);
}