View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Motion vector calculation problem

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

### #1theagentd  Members

Posted 06 March 2014 - 08:30 AM

Hello.

I'm having problems with my motion vector calculations.

The camera is only very barely moving, but as you can see the motion vectors of the bottom left tile are calculated incorrectly when the camera gets too close. I believe the problem happens due to the projection ending up behind the camera (at least one vertex is behind the camera).

I calculate my motion vectors for each vertex like this:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
vec4 previousPosition = previousViewProjectionMatrix * previousModelMatrix * vec4(position, 1.0);
motionVector = gl_Position.xy / gl_Position.w - previousPosition.xy / previousPosition.w;

I am unsure how to fix this. The problem seems to come from the motion vectors becoming extremely large, large enough to cause the whole triangle to receive motion blur after interpolation. Any help would be appreciated!

Edited by theagentd, 06 March 2014 - 08:32 AM.

### #2osmanb  Members

Posted 06 March 2014 - 08:43 AM

POPULAR

This happens if you compute the motion vectors in the vertex shader (because they can't be linearly interpolated). The correct fix is to compute them in the pixel shader (by interpolating current and previous position), then doing a per-pixel divide by W on each. This is (obviously) slower, but should fix this artifact. For what it's worth, our title has this same artifact (we didn't want to pay for the per-pixel computation), but we:

1) Don't really have any triangles that large in our shipping assets.

2) Don't let the camera get that close to surfaces.

... so you never see it.

### #3theagentd  Members

Posted 06 March 2014 - 09:24 AM

Thank you! Your solution worked flawlessly! Since I'm only targeting PC and the additional pixel shader math did not cause a measurable decrease in performance (both run at 140 FPS) I've decided to simply go with accurate motion vectors.

### #4Krypt0n  Members

Posted 06 March 2014 - 10:07 AM

POPULAR

@osmanb

you might reduce the issue by dividing by abs(w), as most of the problem arises due to the flip of x and y when you divide by something negative. it's still not correct, but far less noticeable and you get away with per-vertex cost.

### #5osmanb  Members

Posted 06 March 2014 - 02:29 PM

@osmanb

you might reduce the issue by dividing by abs(w), as most of the problem arises due to the flip of x and y when you divide by something negative. it's still not correct, but far less noticeable and you get away with per-vertex cost.

Interesting. Never thought to try that, but I might give it a whirl. Thanks.

### #6theagentd  Members

Posted 06 March 2014 - 03:48 PM

@osmanb

you might reduce the issue by dividing by abs(w), as most of the problem arises due to the flip of x and y when you divide by something negative. it's still not correct, but far less noticeable and you get away with per-vertex cost.

I tried that after I posted my first post, but it didn't help. I also tried with -abs(w). It seems like the problem is that the motion vector becomes extremely large when a vertex lies very close to (linear) Z=0. Direction isn't really the main problem; it's the length of the vector. I clamp my motion vectors so my motion blur doesn't explode, but the motion vectors are several magnitudes too large even for unnoticable movement.

### #7Krypt0n  Members

Posted 06 March 2014 - 05:53 PM

theagentd, you're right, division by zero (or close to zero) will in most cases lead to bad results. maybe clamping to the near plane might give a reasonable result? something like

xy/max(near_plane,abs(w))

?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.