How do I get accurate and performant coastal reflections?

I’m making a game that requires a high FPS, so I’m trying to find a more performant solution to large reflective planes (coastlines, specifically), I don’t really care how blurry or low-res the reflection is, I just want something close-enough. I’ve been experimenting with lumen reflections, screenspace reflections, planar reflections and scene capture reflections (both box and sphere) and I can’t seem to get a good looking solution that is also accurate. I feel my best bet is a planar reflection but I’m not sure if that’d be any more performant than using Lumen or Screen Space, but those also have a tendency to create weird artifacts and other less-than-stellar behavior.

Most tutorials I see on reflections cover only small, interior spaces, and often consider quality over performance.

I feel like getting sphere reflections to look right would be ideal, since they’re the most performant, but since they take a picture only from one angle having very open levels with lots of height variations inevitably results in reflections looking bad from certain angles.

And using multiple overlapping spheres causes very strange artifacts, not to mention I keep getting RHI crashes that require reverting my maps to pre-capture states.

Planar reflections might work here since I’ve only got the one plane for these, and low-ish poly levels, but even after fiddling with the settings, they seem to cause performance problems on my higher-end machine. I think this is likely due to the size of the planes in question. Such as this particularly large level set on open ocean.

Which looks really good with a planar reflection:

But now this crashes on startup, complaining that
”Uniform buffer bound to slot 4 is not what the shader expected”
And I’m not even sure if this would be all that performant regardless.

Is there a better way?

Frankly, I think Planar reflections are probably your best bet. Screen-space can work if you can control the altitude and angle of the camera relative to the plane (Far: Changing Tides does this well), but for dynamic cameras it’s pretty unacceptable.

Lumen reflections require either baked lighting or lumen GI, so one way or another you’re adding a huge cost. Plus, lumen reflections in their default implementation are very expensive, and it will be occupying a very large screen area.

There are two viable options that I see here: first, DFAO and real-time skylight. DFAO will provide specular occlusion for you, which in a lot of cases is what you really want out of a reflection to begin with. If your lighting is a little more overcast and you have dynamic normal-mapped water, the player might not even be able to tell.

The second would be planar reflections. There are definitely good tools to optimize them, and your performance characteristics and crashes are baffling to me. IK that Epic doesn’t really love them because they’re not super flexible, but check out their guide and I think you can get perf down to a reasonable level.

Yeah, I’m still working on getting the planar reflections to even appear when I run. They show up fine in-editor but I soon as I play they disappear. I’ve created a bunch of test maps and whenever one crashes on startup I just make another, hopefully whenever I figure out why they’re not appearing, that’ll solve the crashing issue too?

I have global plane clip enabled, and reflections set to None. I’m not sure what else could be stopping them from appearing.

I had the same problem, I found a way to fix it but I don’t remember how. Does statGPU show an associated performance cost? That can help you figure out if it’s enabled and just not being shown to you, or if it’s not running to begin with.

What’s your shader model and target platform settings? Are you Vulkan, DX12? Nanite enabled?

I’m only targeting windows for now.

You might want to try changing the RHI to Vulkan with SM6. Sometimes these things are just bugs, and since planar reflections are sort of soft deprecated by Epic, sometimes an API change makes a difference. If it doesn’t work, then you didn’t lose much time investigating it.

1 Like

No dice. Spent some more time tinkering with the planar reflections, but the issue persists. So bizarre, I don’t even get an error.

There is no low cost way.

You aren’t “reflecting" which would imply there is 0 cost. You have to capture something and pipe it out after processing into the material.

You can do this manually in a very inaccurate way by just capturing with scenecapture2d to a texture, and using said texture in a mapped material.

This gets you basic, but won’t work like a reflection since the reflection bounces the angle you look from.

Planar reflections in engine have always been horrible for performance because of the capture PLUS their bad math. And well, it’s not that its bad as in math does math, it’s that it isn’t optimized and it is far too accurate since these are normally reserved for cinematics (so performance isn’t a concern).

Things you didn’t find our yet (but if you fa you will fo)… There is a hard limit on reflection captures before the scene/level/and even the persistent for world composition just crashes. I think 128, but don’t quote me on it. As you know, the more you add the lower the performance or the more computing you have to do beforehand.

Your best bet, if your project is run on the latest version gfx only as a minimum spec is ray traced reflections.

You don’t necessarily need to have everything in raytraced. Reflections alone can be done.

if you do, you should get an engine version where epic has been cut out from screwing things up such as an Nvidia branch.

The cost isn’t cheap, but its also more affordable and less time consuming than both alternatives. If you have to use UE because you cannot use better ones, then realistically, the Nvidia branches are the best rendering/performance conscious ones you can levarage as a starting point.

If I were you, I’d move to a better engine like Cry. Their volumetric based raytracing beats anything epic will ever be able to do before they crash and burn into oblivion… not that cry isn’t going to be obsoleted too, it’s just that at the very least they are responsive to realistic performance concerns.

Also, re the general fafo… disable motion blur, and try to go to something other than TAA. Maybe even try forward shading if you really want to use unreal and can’t levarage an Nvidia branch for whatever reason. IMHO all options blow compared to alternative engine, but you know… you can at least try.

Something I noticed: it looks like the height of your reflective surface changes in your two screenshots: is there a possibility that the planar reflection actor isn’t actually affecting the water at all, and what’s happening when you hit play is that the reflection actor is just getting hidden?

If you hit G with the actor selected, does it look the same as if you hit play? Or if you disable ‘show preview plane’? If that’s the case, then it means the actor is working and just not affecting your water for some reason. Maybe there’s a mesh or material checkbox to check, maybe the bounding box of the planar reflection needs to be altered. Even though the documentation says nearby reflective materials should automatically be affected, in practice there can be alignment issues.