Hello there !
I have been looking at this thread (and others like it) for a while because we also had a similar issue (very likely the same one).
Pretty much exactly what Dmytro Kondratishyn reported in his original post [Content removed] and that I have seen reported in multiple other posts before but none had an actual solution yet (the bug is really hard to repro and only seems to happen in very specific settings, and I don’t think Epic had a repro for it).
Some posts for example :
[Screen [Content removed]
[NVIDIA DLSS enabled causes screen [Content removed]
…
it was also reported in NVidia forums for DLSS a while ago (but I don’t think it’s DLSS specific, I had the bug happens with TSR too and had reports about others also seeing it with differents upscalers) :
Extremely glitchy graphics with DLSS 3.7 plugin in shipping build from UE 5.4.2 game - Gaming and Visualization Technologies / DLSS - NVIDIA Developer Forums
Anyhow, I worked quite a bit on trying to fix that bug in our game and wanted to share what I saw and the workaround I did which so far seems to work for us in case it helps someone find the real issue (I’m really curious to know what it is if someone finds out).
Since I pushed my workaround, I haven’t seen or heard about that bug so I assume it might be fixed, though that bug was extremely hard to repro and as far as I can tell, it seems timing-related so it might just be “hiding” again.
So, first things first, in our case, the bug seemed to only happen only in very specific setups :
- I only was able to reproduce the bug only on 1 of our PC which had a Nvidia 2070. Couldn’t repro at all on a 5080 doing the same thing and looking at the other posts about that bug, I think the bug is more likely to happen on older hardware.
- Disabling separate translucency was fixing the bug for us (but that wasn’t an option)
- The bug seemed timing-related to me, doing the same repro steps over and over again, the bug wasn’t always happening. Also, taking a capture with PIX never showed the issue, in the captures, you could only see the bug in the previous frame render targets and textures but that’s it, the captured frame only ever showed a fixed Scene for me (and I did take a lot of captures to try and get it)
- The bug only seemed to happen for us if we had both “ComposeTranslucencyToNewSceneColor” passes (“AfterDOF” and “AfterMotionBlur”).
- I ended up finding a somewhat reliable way to repro that bug in our game but I can’t share a sample project with the bug since I never was able to repro in a small map, the only way I could repro was on 1 computer only with a 2070 as I said and it was happening in one specific place of our open-world. The way I repro-ed it somewhat reliably for us was to launch the game with DLSS and switch to TSR in game (the other way around didn’t have the bug for some reason), but just to be clear, I don’t think the issue comes from DLSS or TSR per say, I had reports of that bug happening using TSR, using DLSS, or others. It’s just that this bug for me was easiest to repro by switching from DLSS to TSR in-game at some place in our open-world. Doing it that way, I was getting is about 80-85% of the time.
Anyhow, since disabling separate translucency was fixing the issue, I looked mostly at it and ended up finding out that changing inside “FScreenPassTexture FTranslucencyComposition::AddPass” in “TranslucentRendering.cpp” :
PassParameters->SceneColorSampler = TStaticSamplerState<SF_Point>::GetRHI();to :
PassParameters->SceneColorSampler = TStaticSamplerState<SF_Point, AM_Wrap, AM_Wrap, AM_Wrap>::GetRHI();Instead of getting the “stretching” bug effect, I got multiple times the same scene color repeating on screen.
So, I thought it was probably an issue of UVs or Render target resolution in one of the “ComposeTranslucencyToNewSceneColor” passes (“AfterDOF” or “AfterMotionBlur”).
Which is why I tried a few things :
- Adding logs returning the rendertargets resolution and UVs used in the cpp code (in “FScreenPassTexture FTranslucencyComposition::AddPass”) -> Didn’t see anything wrong at first glance.
- Then, I went into the shader “FComposeSeparateTranslucencyPS” and removed almost everything but tried to use a “Coloring scheme” to see what was happening to the UVs used in the shader for “SceneColor”. Basically, I just outputed “SceneColor + a bit of red” if SceneColorUV.x < 0.5f and “SceneColor + a bit of green” otherwise for example (stuff like this), I just wanted to see how the UVs behaved when the stretching bug happened.
Doing this I still saw the stretching bug.
Thing is, since there was two “ComposeTranslucencyToNewSceneColor” passes (“AfterDOF” and “AfterMotionBlur”), one before the TSR (or DLSS, …) upscaling and one after, I had a bit of noise with my “coloring mask” since it was applied in both passes, so I wanted to make it cleaner and added a boolean sent to the shader which was true only for the “AfterMotionBlur” pass and false otherwise and I used that boolean in the shader to only apply my coloring scheme if the bool was true (so only for “AfterMotionBlur” and NOT for “AfterDOF”)
I STILL had the bug this way but here is the interesting part :
- I tried to NOT send the bool mentionned earlier and instead I created a shader permutation to distinguish between “AfterDOF” and “AfterMotionBlur” and only applied the coloring scheme to “AfterMotionBlur”. Should have been similar but doing this, the bug was gone, couldn’t repro it a single time after that even though I had been able to repro it pretty consistently without the shader permutation and just using a bool.
- If I created the permutation but didn’t do any code with it in the shader (for instance, I just commented all the code inside my “#if permutation”), the bug came back.
So, ultimately, to fix that issue, I created a shader permutation and added something like this :
// Final composition
OutColor.rgb = SceneColorSample.rgb * SeparateTranslucencySample.a * SeparateModulationSample.rgb + SeparateTranslucencySample.rgb;
//----------------- start of my change --------------------
#if PERMUTATION
OutColor.rgb = max(0.0f, OutColor.rgb);
#endif // PERMUTATION
//----------------- end of my change --------------------
Towards the end of “MainPS” in “ComposeSeparateTranslucency.usf”.
(The “max(…)” doesn’t do much in theory but without it, the bug was still happening, the important thing is that there is some code to make the shaders distinct).
So, my current unproven theory is that somehow when the bug happens, the second “ComposeTranslucencyToNewSceneColor” pass “AfterMotionBlur” is using some binding/UVs or rendertargets from the first “ComposeTranslucencyToNewSceneColor” pass (“AfterDOF”) which has different render target sizes and UVs (one pass is before upscaling, the other after).
I don’t quite understand how or why it would happen but that is what I’m currently thinking is happening. By creating a shader permutation and adding some small change to make the shaders distinct (even changes which shouldn’t really do anything), I guess I am “forcing” the two “ComposeTranslucencyToNewSceneColor” passes to each actually use the right shader / bindings.
Anyway, I’m not looking at this bug anymore for now since it does seem to be gone in our case with that workaround (I submitted this workaround in our code a bit more than a month or two ago I think), I just wanted to post this in case you want to try it on your end and maybe it might help people to find the real cause of the issue and the right fix.
Best regards,
JB
[Attachment Removed]