Preview of Screen Space Reflections for URP

We are currently working on an implementation of Screen Space Reflections for URP, which we aim to ship in Unity 6.7. This is part of a larger initiative to improve the graphical fidelity of URP. Today we are pleased to show off a first version of this feature, and invite you to try it out.


URP Oasis Template Scene, using Screen Space Reflections on the water.

What are screen space reflections?

The Screen Space Reflection feature produces real-time glossy reflections by marching rays in screen space and sampling the camera’s color and depth buffers at various points along the ray. The technique can produce fairly high quality reflections of visible objects, which instantly update to reflect changes in the scene, without much setup or authoring steps required.

Screen Space Reflections can only use information that is visible on screen. When a reflection ray travels off screen, or behind an object, there is insufficient information to calculate a hit point. In those cases, a fallback cubemap will be used - either from a nearby reflection probe or from the skybox.

Getting started with the feature

A full guide on setting up and configuring the feature is provided here: URP Screen Space Reflections Guide. The ā€œEnabling Screen Space Reflectionsā€ section shows how to enable the feature in your project, while the ā€œConfigurationā€ section explains all of the settings exposed by the feature.

To try out the feature, get the latest Alpha release (at least Unity 6000.6.0a7).

Once you have tried the feature, please help us concentrate our efforts on improving it by filling this short survey: URP Screen Space Reflections - Product Experience Feedback.

If you run into any bugs or issues not described in the guide, please let us know in this Discussions thread.

FAQ

Does the Screen Space Reflections feature work together with Surface Cache GI?
Yes, the features can be mixed freely. Surface Cache provides diffuse lighting, while Screen Space Reflections provide specular lighting. The features simply add their contribution together.

Can Screen Space reflections be used with baked lighting and/or reflection probes?
Screen Space Reflections are applied additively on top of existing baked lighting, and are fully compatible with it. In cases when rays travel off screen or behind objects, reflections are instead calculated using nearby reflection probes, if there are any.

Does the Screen Space Reflections feature require hardware ray-tracing?
No, we do not require hardware raytracing, nor do we use any kind of software equivalent. The technique works entirely by marching rays in screen space. In the future, we may extend the feature with raytracing capabilities for greater fidelity.

18 Likes

Bumping the post since it was just made public.

Its Been 84 Years GIFs  Tenor

Still, thank you guys.

4 Likes

Solid implementation! The only issue I’ve found is when Reflect Sky toggle is enabled, while you moving empty spots between reflections will have black trails:


Also I’m not sure if bilateral upscaling is working or not as I don’t see any difference when switching between billinear and bilateral. And I’m curious if it’s possilbe to have a better upscaling options in future, maybe FSR-based or something like that, because currently half and quarter resolutions are not really usable with such basic upscaling. Especially on things like water and puddles low resolution is very obvious.

I think that’s all my complaints. Overall great job, guys. I’m happy we finally having SSR in URP :partying_face:

1 Like

Might be the best SSR implementation I’ve seen, HDRP’s one was garbage. Please consider extending this with RT, I think it should be a high priority!

Another thing I’d love to see is depth/distance-based blur

1 Like

The only issue I’ve found is when Reflect Sky toggle is enabled, while you moving empty spots between reflections will have black trails

Hmm, that’s strange. Do you see this in both the scene and game view, or only scene view? The scene currently doesn’t use proper motion vectors, which can cause artifacts like that. It’s a long standing limitation of URP - no motion vectors in scene view, but we are working on removing the limitation atm.

Also I’m not sure if bilateral upscaling is working or not as I don’t see any difference when switching between billinear and bilateral.

The difference is pretty subtle depending on the scene, both options use a tiny bilinear kernel, but one additionally applies bilateral weights based on the normal. Here’s an example that shows it, image is cycling between nearest neighbor (not exposed), bilinear and bilateral.
3115a698-cfb3-4080-98a7-132ca22388bd

maybe FSR-based or something like that, because currently half and quarter resolutions are not really usable with such basic upscaling.

We’ll definitely keep it in mind. For the time being, you can hide/mitigate this somewhat by using the Temporal Filtering setting, increasing the roughness of your materials, or applying more noisy textures. Upscaling fully mirror-like reflections, like reflections on a still lake, is pretty tricky.

Please consider extending this with RT, I think it should be a high priority!

Before Surface Cache GI, there wasn’t really a precedent for using raytracing or compute in URP. That is changing now, so we have been considering using raytracing in some capacity for reflections.

ā€œRaytracingā€ can mean many things. One interpretation is to do what HDRP does: The user can select between raymarching, raytracing or ā€˜mixed’ mode (where we first raymarch, then continue rays that go off-screen using raytracing). This might be more tricky to achieve in URP, especially in the presence of custom shaders, since it requires being able to evaluate materials during raytracing.

Just out of curiosity, did you have this kind of thing in mind, or are you thinking of something else?

Another thing I’d love to see is depth/distance-based blur

Yep, this one is already on our list of potential future improvements :slight_smile:

It’s a bit tricky with our setup, since just basing the blur radius at each pixel on the depth/ray distance will create hard seams across what should be smooth reflections at depth discontinuities. Should be doable, but will probably incur a performance penalty due to another filtering step.

We’ve also considered a stochastic accumulation mode (what HDRP calls ā€œPBR Accumulationā€) as an alternative to blurring for higher-end platforms, but I’m a lot less certain about if/when we will want do this.

Yes I was thinking of how it’s done in HDRP

1 Like

In both scene and game view. Screenshot is from game view.

Thanks, I’ll see if I can reproduce it tomorrow.

So for the reflective surface the docs says we add:

#pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION

But it doesn’t say much else…

How do we get the SSR result for a given pixel in a custom frag shader?

I’ll repost what I posted elsewhere when i checked this with some adjustments :stuck_out_tongue:

SSR is critical for displaying metals properly, so for me a key test is this gold example rendered in blender cycles.

Now we don’t expect realtime to perfectly match cycles, but…

Eevee displays similar quality with limitations, namely the specular occlusion and blur of the SSR over distance.

Now lets look at Unity.

Not bad, now this is with ā€œStandard IGNā€ SSAO not the new GTAO. Which I know is not related to this thread but I want to point out any specular occlusion seems to rely on it. In blender SSR and SSAO seem to be handled at the same time.

This is GTAO which is less aggressive (changing to 1.15 strength helps more but that might have consequences elsewhere)

That said it DOES seem like the SSR has some impact on specular occlusion when SSAO is on. This is because the SSR reflects the SSAO so that’s something.

For comparison here’s no SSR.

No SSR

Blender:


Unity (No SSR no SSAO):

Main take aways:

  • SSR needs the option to blur by surface distance. That would elevate it a lot.
  • SSR could benefit from additional specular occlusion.
  • Object thickness seems mandatory, the presets didn’t do it for me.

Here’s the settings I use.

Here’s the blend file if anyone wants to test.
Gold.blend (27.1 MB)

4 Likes


Poll has an error, says all that apply but only lets you pick one, in this case i’ll choose my lowest platform…

Have you guys considered noise blur? It’s not as pretty but it’s damn fast. I use that for another of effects cause it kinda just works.

I’m pretty sure it’s just part of getting the environment reflection.

Thanks for reporting, the survey is now updated to allow multiple choices.

1 Like

Wdym part of environment reflection? Still not very clear how I sample in the frag shader.

It’s already part of Unity’s BRDF, so any shader not using custom lighting will incorporate it into its lighting model natively.

You can also follow the breadcrumbs of the _SCREEN_SPACE_REFLECTION keyword which leads to the SampleScreenSpaceReflection(screenPos, positionWS, smoothness); function being used to sample SSR specifically.

@StaggartCreations is correct. I added a little more information about this to the document. You can see the function that samples environment reflections (Both from SSR and reflection probes) here Graphics/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl at master Ā· Unity-Technologies/Graphics Ā· GitHub

I’m so grateful for this it’s so beautiful. It’s way too late, it’s sooo, so late I’m really mad about this.

3 Likes

Object thickness seems mandatory, the presets didn’t do it for me.

You mean you had to adjust the object thickness from the presets? It’s kind of to be expected, since reasonable thickness is highly dependent on the scene. If we set it too low, you get holes in the reflections, but if we set it too high, the reflections will look stretched.

SSR needs the option to blur by surface distance. That would elevate it a lot.

I think so too, it’s on our list :slight_smile:

Have you guys considered noise blur? It’s not as pretty but it’s damn fast. I use that for another of effects cause it kinda just works.

I’m not sure which technique you are referring to. Do you mean shooting rays in random directions each frame (yielding a noisy image), then accumulating over time? That would give you distance based roughness at the cost of requiring temporal accumulation, which has its own set of issues.

To be clear, what I was talking about is an inherent issue to blurring the reflections in screen space. No matter the kind of blur, if you base the radius off ray distance, you’ll see the depth discontinuities. Here’s an example image to illustrate what I mean

That can be mitigated in several ways, for example by blurring the per-pixel ray distances before using them to blur the reflections. Still not perfect but works decently:

Let me know if you had something else in mind.

4 Likes