Raytraced reflection doesn't shadow correctly

Continuation of the issues I outlined in this thread Raytraced reflections don't have shadows or GI - #6 by eggboy5000 - Rendering - Unreal Engine Forums (I split the thread to get a better topic name)

I tested with a real world asset from Megascans, cliff asset (rcygn). The roughness is quite high and it appears the reflections are not shadowed at all just simple lookups to the skylight. Comparing to the pathtracer looks washed out.

I couldn’t find any console vars that help, am using these settings on the ppvol:-


Raytrace vs Path tracer (spec=0, matches)

Raytrace vs Path tracer (spec=1, washed out shadows)

It appears that raytracing is not used at all at higher roughness levels. If I switch between screen space and raytraced reflections there is no change on the cliff asset. Yet on other assets with reflection but less roughness it very noticeably changes. That implies screen space is actually being used on higher roughness areas despite max roughness set to 1 for raytracing?

Is this a bug or have I missed something??

How it basically works, in one aspect, is the ray tracing reflections —> SSR transitions across the roughness spectrum of 0-1. So, the closer to 1 roughness a material is, the more it’s using SSR and not RTR. That’s from how I learned it so far, at least, in video / reading. However, I’m wondering if roughness value 1 is included in the function or if it’s specifically less than 1. IOW, is it RTR is applied up to and including 1, or is RTR applied at roughness values 0.999999… and lower? Since it has a gradient of SSR vs. RTR use according to how close to the threshold value it is, it’s probably not worth worrying about. I notice the RT spec=1 image is far more washed out than the path tracer. That’d seem to imply there’s extra diffuse lighting or a subtraction of color, which I think wouldn’t occur with SSR unless it was set up to do so.

I can understand a transition if the raytrace max roughness is < 1, but I have it set to 1 so I’d expect it to only use raytracing.

Looking at reflection only, the washed out look must be due to SSR and no raytracing being used.

Then if I force the roughness max down to 0.5 on the shader, raytrace and path tracer look a lot closer.

There must be a way to enable only raytracing for reflections?

Add a reflection capture to the scene, then build the reflection captures. Does it look different?

Yes if I add the refl capture it seems to add a bunch of extra light to the scene. Interestingly if I force the roughness on the material down to 0.5 the reflection capture has no effect.

Raytraced w/ refl capture

Raytraced roughness 0.5 w/ refl capture

Yeah I tested it as well, it is definitely blending in reflection captures at max roughness.

Note the orange hue matches the reflection capture

I don’t know if there’s a way to force only raytraced reflections, but the best solution obviously is to just add reflection captures to your scene, at such high roughness values the difference between raytracing and captures is virtually non existent:

Edit: just to add, it really starts becoming noticeable at around 0.6+ roughness.

I tried using the console command to set the max roughness to higher than 1 but it didn’t seem to make any difference, it seems 1 is a hard cap.

You should submit this as a bug, you can link back to this thread.

Though I suspect this is by design, there really should be a way to force only raytraced reflections because captures can’t update in realtime so it’s not suitable for shots with strong lighting transitions.

Good to see your results match what I was getting.

Unless I’m missing something reflection captures don’t have anywhere near the fidelity of raytraced reflections as they don’t have any way to include local occlusion. Not really an option for me. I assume it’s built this way for speed but for “offline” projects (film,vfx) that isn’t as much of an issue.

I’ll submit a bug report, thanks.

Perhaps I’m misunderstanding what “local occlusion” means but captures in UE4 are localized to the radius of the capture, meaning if you move the camera in toward a reflection, it will get larger and it will get smaller if you move the camera far away. It requires some reflection mixing in order to accomplish but it looks far better than the usual “infinite distance” cubemaps.

If by “local occlusion” you mean accurate parallax within an individual capture then yeah, you can’t really accomplish that with captures. However as I tried to highlight above, the difference is virtually indistinguishable on a surface this rough, and the less rough the surface is, the more raytraced reflections will be blended in, so I don’t see this as a huge issue but then I mainly make realtime content, so my standards are undoubtedly lower.

Also I discovered reflection captures CAN update in realtime, via the console command: r.ReflectionCaptureUpdateEveryFrame

Fair warning, it will be VERY expensive to run that with a lot of reflection captures. Not ideal but it will work if you need a solution immediately.

You might also be tempted to drive up the resolution of reflection captures, I would caution you against going too high as they are HDRs and require a ton of GPU memory.

Is the scene using HDRI? That can introduce extra lighting depending on its settings, which could be adding to the brightening and under-saturated look of the RTR. This is especially the case if a second skylight and/or directional light is added because the HDRI already has a dynamic skylight. If one or both of those lights are stationary, then it could require adjusting indirect lighting intensity or another light property. There’s also how lightmaps mix with reflection captures and could be over-brightening the cliff asset. To reduce it, go to Project Settings > Rendering and enable “Reduce lightmap mixing with reflection captures”. If it doesn’t work, then I’d suspect more a problem with RTR and roughness threshold.

I think so too about threshold increasing the use of RTR at different roughness values, including 1. But SSR seems to be quite a tradition in UE.

I can understand to some extent, that they blend in the reflection captures at such high values, because otherwise you would need a really high sample count (probably several 100 samples) to get smooth reflections (i mean, not noisy). The more rough it gets, the more samples/rays the raytracer will have to send out to capture more of the surrounding to create the average color of it for reflection. And with roughness being 1 = 100 percent, you force the raytracer to basically shoot out samples/rays in ALL directions, 360 degree, which then would basically just return the base color plus an average of the light from the whole surrounding.

However, i also would prefer a raytraced only option, since there are cases, where you cannot work with reflection captures, or you would have to rebuild them constantly. Thinking about a high speed chase, f.e. airplanes (through clouds) or spaceships (cars are usually too shiny ^.^ unless we talk about Mad Max cars :slight_smile: ), that result in a constant change of locations and different light situations at almost every frame.

I am like, 99.999999% certain that SSR cannot be used with raytracing. Raytracing only mixes in reflection captures.

Have you checked the new 4.26 Preview 4? There is a new r.Raytracing.Reflections cvar available, R.Raytracing.Reflections.Hybrid, and if set to 1, then it indeed mixes raytraced reflections with SSR.
Had tested it with a subsurface scattered material, from which the subsurface didn´t get reflected from the raytracer, the hybrid mixed in the ssr reflection for that part.

You’re right, that’s interesting. It’s disabled by default, doesn’t look great on mirror surfaces.

UE 4.25.3 is already a hybrid of ray tracing and other reflections, depending on which reflections are being utilized / enabled in the scene. It’s why the tooltip for the Roughness threshold describes it as the roughness at which RT fades or becomes unused. There’s a video by a professional which he shows disabling SSR is important for seeing the actual results of ray tracing reflections because when SSR is off there won’t be reflections when RT isn’t rendering them. Adding a reflection capture requires other settings to get the right results, not simply enabling the fallback cvar.

As I understand it, reflection captures render the scene from their position and reproject that onto a sphere of said size for reflection. So any occlusion inside of that volume (shadowing) is not represented in the result. The rock face in my example is really uneven so to get something even close to raytraced reflections you would need to add a lot of reflection captures all over the surface.

I did a test where I put some reflection captures in. You can see it gets somewhat closer to the path tracer in that area.

The tooltip is a bit vague, “smoothly faded when close to threshold”. What does that mean exactly? As it seems to start at around 0.6 when the max = 1. Maybe there should be a switch to turn that off altogether.

Do you have a link to that video?

Is the surface normal involved in local occlusion calculation? I would think it has to be to an extent. And reflection captures are probably limited in recreating the surface normal, such as the cliff material / mesh, which is partly why one capture doesn’t have the same shading result as RTR or SSR, or the path tracer. The 1st screenshot above, without the captures and HDRI, has the simplest shadowing of the 3 pictures because it’s not getting the ambient term of lighting from the HDRI (e.g., picture 3) and it’s not getting the black of reflection captures like in picture 2. Read up on the reflection captures, and without proper aligning / brightness / radius, the reflections can appear black or partly black. Picture 2 is similar to 3 as far as there is shadowing, but it’s inaccurate and has made details not visible.

The shadowing is represented in the result of the reprojection in capture probes, but it’s not as accurate as RTR without the noise.

Yes that is a problem, in realtime for assets where it is important we would normally use a bent normal map to get better reflection occlusion:

Unfortunately I have no idea if it works with raytracing.