Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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.

  • You cannot reply to this topic
6 replies to this topic

#1 theagentd   Members   -  Reputation: 602

Like
0Likes
Like

Posted 06 March 2014 - 08:30 AM

Hello.

 

I'm having problems with my motion vector calculations. 

 

jFx9Yii.jpg

 

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.


Sponsor:

#2 osmanb   Crossbones+   -  Reputation: 1628

Like
6Likes
Like

Posted 06 March 2014 - 08:43 AM

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.



#3 theagentd   Members   -  Reputation: 602

Like
0Likes
Like

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.



#4 Krypt0n   Crossbones+   -  Reputation: 2627

Like
5Likes
Like

Posted 06 March 2014 - 10:07 AM

@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.



#5 osmanb   Crossbones+   -  Reputation: 1628

Like
1Likes
Like

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.



#6 theagentd   Members   -  Reputation: 602

Like
2Likes
Like

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.



#7 Krypt0n   Crossbones+   -  Reputation: 2627

Like
0Likes
Like

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.



PARTNERS