ndepoel / FSR3Unity

FSR 3.1 Upscaler integration for Unity built-in render pipeline, with support for DX11, Mac, Linux and consoles.
https://discussions.unity.com/t/open-source-fidelityfx-super-resolution-3-1-fsr3-upscaler-for-unity-birp-dx11-ppv2-hdrp17-multi-platform/917847
MIT License
234 stars 29 forks source link

Motion through walls #16

Closed ineedmypills closed 1 month ago

ineedmypills commented 1 month ago

In my horror game, TAA and FSR allow you to see enemy movements through walls, which is undesirable. Is there any way to fix this?

Example: https://github.com/user-attachments/assets/e13092c1-5a2c-4eef-a6ac-dec3f584b0f7

ndepoel commented 1 month ago

Yeah, this is a known issue with motion vector rendering in Unity. On some platforms Unity applies a small Z-bias to the vertices of dynamic objects when drawing object motion vectors, which causes them to be drawn on top of static objects that don't have this bias.

I had to deal with the same problem when integrating FSR 2.2 into Isonzo:

ghosts-15

The issue has been reported to Unity as well but they don't seem very eager to address it: https://issuetracker.unity3d.com/issues/motion-vectors-bleed-through-any-geometry-when-using-urp-temporal-anti-aliasing

The issue lies with these lines in the object motion vector vertex shader code. For BiRP, in Internal-MotionVectors.shader: image

For URP, in ObjectMotionVectors.shader: image

For HDRP, in MotionVectorVertexShaderCommon.hlsl: image

As you can tell from the comments, it's an old hack by Unity to work around some kind of issue with dynamic batching. Annoyingly the _MotionVectorDepthBias and unity_motionVectorParams variables are part of constant buffers set by Unity internally, so there is no way to control those values from your game code directly.

The first thing you can try is to disable Dynamic Batching in your project's Player Settings. Some people have reported success with this, as it should trigger Unity to set this bias value to 0. However other people said this has no effect, so your mileage may vary.

Alternatively, you can override the motion vector shader code in your project and remove the lines I mentioned above. Depending on which render pipeline you're using, this can be as simple as creating a custom shader and setting it as your default motion vector shader.

For BiRP, this is done in the project's Graphics Settings, by setting the built-in Motion Vectors shader to a Custom Shader and dragging in a copy of the default Internal-MotionVectors shader with the offending lines removed: image

For some versions of URP, it is possible to set a custom Object Motion Vector shader on your Universal Render Pipeline Assets by switching the Unity inspector to Debug mode and opening the Shaders list: image

However it seems that newer versions of URP removed this shader assignment, so this solution might not be possible for you.

The last solution, and the one that's required for HDRP, is to use a custom package for your render pipeline and modifying the object motion vector shader code in-place there.

I hope that helps! Let me know which solution works for you.

ineedmypills commented 1 month ago

Thank you for your help! Disabling Dynamic Batching helped.