[UE5] Is Output Velocity really always necessary?

I welcome all you UE developers!

I’d like to start a thread about the need for Velocity Pass and Output Velocity options in UE5. You know, this is now always enable in UE5 and we get great quality TAA and Motion Blur with reduced ghosting effects. That’s fine and it works great in most cases. In addition, we have the Output Velocity option for translucent materials, which gives us more options for rendering such objects.

But, some time ago I encountered one rather unobvious problem, the easiest solution to which would be to disable writing to the velocity buffer. This applies to very large scale objects, with a radius of several thousand km, which move around a point in space at fairly high speeds. This situation creates a rather strange behavior in TAA and Motion Blur - we see the opposite effect of using the velocity buffer. This generates a ghosting effect on such large-scale objects with a write to the velocity buffer.

If I turn off post-processing, such as TAA and Motion Blur, this ghosting effect disappears, the object moves smoothly and evenly, as far as it can be visually noticed. I can assume that this is due to certain calculations errors at these scales and it would be almost impossible to overcome, even using double-precision calculations as I do, there are still possible errors.

To be more accurate, I made a short demo video:

A great option for solving this would be the ability to disable writing to the velocity buffer for such an object. I did this using translucent material and it got rid of the ghosting effect with the Output Velocity option turned off. And it brought the effect back again if the option is on. But unfortunately, this option, for some reason, is not available for opaque materials, although it would be very helpful in these situations.

I spent several weeks trying to find a solution for this. But still no success. Maybe there are other ways I don’t know about. Maybe some of you know?

Also, I’d like to know why we don’t have the option to disable Output Velocity for opaque materials, as is done for translucent materials? Is there some reason for this? I think such an opportunity would be very useful in situations like mine.

There may be a way to use the “previous frame switch” node to fix this. It’s normally used in the opposite manner - adding motion vectors for situations where there isn’t one generated automatically. But it might be able to cancel out the existing motion vectors if you use it to generate an opposite vector.

I’m trying to play with it, but so far I’m only getting worse results. Or the same.
The thing is, with post-processing turned off, I don’t see any problems with the object. It moves very smoothly.
But TAA creates a strong ghosting effect.

Ghosting is caused when velocity is wrong or missing because TAA blends multiple frames. When you disable TAA, you are no longer blending frames, therefore there is no ghosting.
If you created a blueprint that tracked the position of the object in the current and previous frame, then you could find the vector between these positions. Thats vector, or perhaps it’s inverse is what you’d need for the frame switch.
Is the planet modeled that large, or is it scaled up? If it’s scaled up, try changing the build scale for it in the mesh settings so that it’s scale in engine is closer to its import size.

Yes, I understand how it works. But no way to get rid of this strange behavior. I tried to use the reverse vector and apply the previous frame switch. Unfortunately, there was no improvement.

I tried both. No difference between using a scale or a large mesh for this. Ghosting is present in both cases.

Maybe try factoring rotation into the frame switch too somehow? I think the RotateAboutAxis node could be used to negate motion vectors being generated by the spinning. If that doesn’t work I’m unfortunately out of ideas. Like you said, there are several layers of large numbers being stacked so it seems like the error margins are just piling up.

I’m still trying to use it. With no positive results. In any case, this is unlikely to fix it completely, as it will just return the pixel to the previous frame. Whereas TAA still uses data from multiple frames. Thus, the problem will still remain, but with info about earlier frames. As it seems to me.

I still think that the problem is directly in the velocity buffer, because when you turn off the TAA it moves smoothly. It’s not clear to me why we can’t turn off output velocity for opaque materials. That would be the ideal solution.

Even though TAA blends multiple frames, if you can correct the previous frame vs current frame only, that will fix all blended frames because the older frames would’ve been already corrected and stored in the corrected state when they were the previous frame.
But I agree, you should be able to opt in and out of motion vectors on either side a per object or material basis.
Unfortunately without that, the previous frame switch is the only method I know of to artificially alter the velocity pass. One last note, make sure that output velocity from WPO is enabled or else the previous frame switch won’t do anything.

It’s enabled in my project. Still can’t fix it that way.

My other option is to try to modify the sources of the UE. I think I was able to find the part where the buffer assignment happens. There are very similar functions separately for opaque and translucent. The function for semi-transparent has a boolean check, while the similar code for opaque does not. I don’t think there should be any difficulty in adding it.

To be honest, I usually try not to resort to this kind of manipulation of the source code.

Yeah, if it can be avoided… But Epic has refused to do it themselves in the past when they were asked. So I don’t see much choice.

So… If anyone is interested. The only solution I was able to find was to modify the engine. I added a boolean for a static mesh component that excludes the object from the velocity buffer. It works. Of course, it’s only in my local branch.

3 Likes

Please point me in the right direction where in code should I check for flag? (where is write to velocity buffer). Thanks

Hey, where exactly are you making this check?

Hi, I’m trying to do the same thing but I’m less familiar than you with buffer assignment in unreal. Can you tell us in which function you put this boolean check please? Thanks