Translucent Materials behind Other Translucent Materials Ignore Refraction

Hey there,

I’ve got the problem as detailed in this video:

In words, the problem is the following:

  • refraction works through translucent materials, until another material that also has translucency and/or refraction enabled is seen through the first translucent object
  • for example: the ocean in the distance appears to render on top of where you would expect the refracted image of objects below the hill. If you pitch the camera down so you don’t see the ocean, the effect looks as expected
  • another example is that, given the refraction of a translucent object, we’d expect other translucent objects to be rendered “bent away” from their actual position in world space (since that’s what refraction is) – however, as we can see when I look through the crystal tree, the other objects using the same Material are seen “cutting through” the refraction and are shown as if the Index of Refraction is 1.00

Things that do work after applying fixes / work-arounds (see below):

  • refraction looks mostly correct (some artefacting at oblique angles but that can probably be worked on some more)
  • translucent materials when seen through other translucent materials are still translucent
  • Objects get doubly refracted when seen through two surfaces that refract (even though the second surface isn’t where you’d expect it given the first object in your way)

Things I’ve already tried, and work-arounds I’ve had to apply:

  • Originally I was using Substrate, but the refraction seems completely broken in this system still - I was seeing things rendered twice through the translucent materials, and then it wasn’t even actually properly refracted in the duplicate image
  • So this is using the UE4 Materials instead; or rather, a Substrate UE4 Unlit Shading conversion node that feeds into the Front Material (see image of Material setup, below)
  • Tried various Lighting Mode, Translucency Pass settings in Material Settings; tried Lumen and not-Lumen, and no Global Illumination whatsoever; tried Hardware Raytracing and non-Hardware Raytracing; set PostProcess Volume to Translucency Type: Raster (see also: UE5 severe problems when rendering translucent and reflective materials simultaneously - #20 by Durghan)
  • Tried multiple indices of refraction (close to glass, water, ice; the refraction in this material is closest to amethyst, which is what I’m trying to emulate here)

Any insights would be kindly appreciated!!

P.S.
I will also describe the Material setup in words as I’ve seen images on this forum break over time during migrations to different forum software; so for future Internet peoples…:

  • Substrate Material
  • Select root node
    • Blend Mode to TranslucentColoredTransmittance
    • Lighting Mode to Surface ForwardShading
    • Translucency Pass: After DOF
    • Refraction Method: Index of Refraction
  • DistanceFieldApproxAO node with default settings (BaseDistance=15.0; Radius=150.0; Num Steps=1; Step Scale=3.0) plugged into root node’s Ambient Occlusion
  • ScalarParameter IndexOfRefraction with default value 1.545 (IoR of amethyst crystal) plugged into root node’s Refraction (Index of Refraction)
  • Substrate UE4 Unlit Shading (UE4US) node plugged into root node’s Front Material
    • using Material Function: SMF_UE4Unlit
  • 3VectorParameter plugged into UE4US node’s Color (V3)
    • value: 0.4; 0.5; 1.0; 1.0
  • ScalarParameter CoverageWeight with value 0.6 into Opacity (S) of UE4US node

Here’s another great example of the problem: based on the “true perspective”, we would expect the crystal Quinn, who’s standing next to the white box, to appear in a similar position in the warped perspective of the cone, cylinder, and sphere. But she’s not; instead, she only shows up if we look straight through one of those objects, appearing where she would be if our lens had an index of refraction of 1.00.

Compare to what it looks like when I use Quinn’s default materials, above. She shows up in the refracted images within the crystal objects where we would expect her.

My best guess is that this has something to do with render passes, the depth buffer and other graphics processing stuff like that, which I only have a very limited understanding of.

I’ll update you if I find out any work-arounds (or of course: the fix!!).

P.S.
Incidentally, I notice another problem in this image: in the sphere, we can see a near clipping plane or something similar “cut into” the white box inside its refracted reflection of the scene. Not sure about that one just yet.

Unreal engine’s transparency system has undergone significant changes since I last familiarized myself with it, so my knowledge is likely already outdated, but it definitely makes sense that you are having issues.

Unreal engine primarily resolves refraction in screen space, so it would make sense that multiple layers would cause issues, as it is only performing complex lighting calculations for the first layer of refraction to begin with. I know that lumen does support multiple bounces of correct reflection and refraction (at considerable expense), but I believe that only applies to reflections and not the GBuffer.

As for why the refractions are cut off, since the refraction method is screen-space, when it has to gather data outside of screen-space, it can easily hit a point where it simply doesn’t have the depth buffer information to trace into. There’s no real fix for that because it’s a product of the way refraction is calculated to begin with. I’d suggest using RT refraction, but it simply doesn’t work correctly anymore, alas.

1 Like

Yep, all of that makes sense, thank you! It makes me wonder if this is something we’d have to try and write a custom solution for, or if this is something that we’ll have to give up on and design around.

I’ll keep messing with it (and shaders in general) to see if I can get the look and feel that I want without causing immersion-breaking effects like this.

1 Like

true refractions may not work any time soon. the screenspace method has this “issue” that you would have to render back to front. so the farthest object is refracting correctly, then the nearer objects refract the refracted look of what’s behind it. basicly backbuffer slices/layers. this is expensive in terms of fillrate cause you have to overdraw. and it doesn’t help that glass is already rendered late in the pipeline, post opaque objects. hence why the player model is already in the backbuffer. no real way to fix that, than well… draw back to front.

I’d have to believe there are workarounds, but my first question would be what your art direction/scene targets are, and what your budget for writing custom systems are. Are your requirements for a fully dynamic scene/lighting? Are you able to cache lighting? Can you make non-hero refractive effects cheaper?

The long tail problem of recursive reflection/refraction can be a serious performance drain, but it’s probably possible to make optimizations based on your content. All depends on what you’re willing to sacrifice.