Game Development Community

1.5 1.6 1.7 - Camera Jitter

by Benjamin L. Grauer · in Torque Game Builder · 07/17/2007 (12:59 am) · 190 replies

When the camera is mounted to a moving sprite, the sprite and the background are trembling (when moving).
Especially visible when there's multiple parallax backgrounds. I have the sprite moving using setlinearvelocity at about 50 and the camera mounted with a force set to 0 or higher than 5, the design screen size is 100*75 on a game resolution of 1024*768. Also, it is clearly more visible with vertical sync (and vertical sync is more than necessary for high resolution). The shaking is not something constant, but it is happening very often. When it happen, it seems like the camera go in the wrong direction then catch up back for the time of 2 frames (so, the lower is the framerate, the more remarkable is the issue).

I just tried a workaround by not mounting the camera. For that, I updated the camera position at the player position in updatescene callaback, using getrenderposition to get the exact drawn sprite position... With no success, everything is still trembling a lot.

It could be many things causing it : something with drawn sprite interpolation or camera interpolation or some updating no more happening precisely on each frame. If someone could take a look at it, I would appreciate the help.
#121
02/22/2008 (5:56 pm)
Melv,

I received your code changes and the good news is that I don't currently see any jitter, none at all.

But... at first I was having problems with all my mounted sprites moving perfectly except one which was very stuttery. The stuttery sprite had the right mRenderTickPosition every frame but was obviously not being drawn there. Took a while to track down but it turns out that every update I adjust the rotation and size of my main player sprite, which causes updateSpatialConfig() to be called, which ultimately changes the mWorldClipBoundary. Thus the player was jumping to the mPostTickPosition ever frame and ignoring the interpolations.

I knew that changing position directly was likely to be a problem eventually but wasn't thinking about my rotation and size changes. I'll have to rethink how to do what I need to do. Probably move such things outside of "onUpdateScene" for one :)

Anyway, the end result is that my jittering is gone. I shouldn't say that, I know, because I always notice something right after I make a post.

Thanks.
#122
02/22/2008 (6:14 pm)
To solve my rotation/size changing issues, I moved all my "onUpdateScene" code to a new function named "onProcessTick". Now everything's working fine.

Just needed to insert the following two lines into t2dSceneGraph::processTick():
// Update Graph Time.
    mSceneTime += ITickable::smTickSec;

// insert next two lines here...

   if (!getIsEditorScene())
      Con::executef( this, 1, "onProcessTick" );
I'm not 100% sure that's the best place for it, but it works for now.
#123
02/22/2008 (6:33 pm)
@Ken: You should already have an ::onUpdate() call for objects that receive ticks that is designed to replace the ::onUpdateScene() frame refresh callback.
#124
02/22/2008 (6:49 pm)
@Stephen: I considered using the ::onUpdate() but this way I can process all my global updates at once without worrying which objects have already been updated and which order they were updated in. It might turn out that I could use ::onUpdate() without any issues but... I'm lazy right now and don't want to introduce possible problems :)
#125
02/22/2008 (7:20 pm)
Ken,

That's great news!

You'll be pleased to know that I have been looking at how flexible T2D can be without interrupting the current tick in progress and there are many changes I can make to allow stuff like size/rotation during a tick.

I just wanted to get the ticking working first. ;)

Melv.
#126
02/22/2008 (8:22 pm)
Guys,

I've sent an email to Benjamin who's still having something go wrong in IW. It could well be a calls that are causing ticks to abort.

To that end, I'm going to add a little instrumentation and a tick-guard that will create a metric named "Tick Aborts". This will tell you how many tick-aborts were processed each frame for all objects. I'll place it on the debug-banner.

This should prove useful to at least know if you're potentially causing problems with the ticking.

Melv.
#127
02/23/2008 (10:43 pm)
@Melv, it makes me feel good about TGB and GG to know that there are people like you, determined to fix these pesky bugs. I posted yesterday in the forums with almost the same jittering problem. Someone directed me to this post and now I eagerly await your findings.

When a solution is found will it be added to a future build of TGB? If so I will patiently await the new build as I am not ready to release anytime soon. If not, I may make the source code changes after you provide your final conclusion.

Without trying any of the source fixes above, I did notice that the more work I do in my onUpdate calls, the more prevelant the problem is. Also, the particle effects as mentioned seem to jitter to their own beat, but that maybe because I have an overload of particles right now (1000+).

Thanks Again,
Bruno
#128
02/24/2008 (11:49 am)
Bruno,

Thanks for the praise. :) I guess I wrote T2D and the tick-physics so I guess it's clearly my responsibility to fix it. ;)

If you're working on a PC I can send you an executable to try out but I'll warn again that it shouldn't be used as an official release or be distributed as a production build.

Also, take care to read abov and make sure you're not constantly changing positions of objects. if you're not doing that then this build will hopefully resolve your problem.

Can you give me an email address I can send it to?

As a side note: Benjamin has come close to isolating which aspect of his game is causing the problem. He has at least removed parts of his game to a point where the jitters have gone away. I'll report back when we find out exactly what's causing it in his case and if I can provide a fix for it.

Melv.
#129
02/24/2008 (4:13 pm)
@Melv, I'm not using any setPosition calls, just setLinearVelocity for everything. You can send the test build to bcampolo at bantamcity dot com.

Thanks,
Bruno
#130
02/24/2008 (6:14 pm)
Email sent.

Let me know how you get on.

Melv.
#131
02/24/2008 (6:39 pm)
@Melv, thanks for the build. It did not seem to correct the jitter. I tried it with particles on and off and the particle jitter seems to jitter at its own rate (different from other things on the screen). It may have been slightly better with your build, but not very noticably.

Sorry for the bad news... my problem may be different from Benjamin/Ken's?
#132
02/24/2008 (6:49 pm)
Bruno,

BTW: Did you try Kens demo above? Does that break-down?

Anyway, It's not bad news at all. I didn't expect this to solve everyones problems because I don't think everyones problem is the same. Indeed, I did a special build for Benjamin that put up a warning when a call was made that reset the tick on an object and there were lots of instances.

I am currently working with Benjamin to find out exactly what it is in his demo that is causing the problem. It seems that in his case, there may be something in the scripts that is causing the effect but we're not sure yet.

I'm pretty convinced though that this fixes the case of mounted-ticking which is what I targetted, nothing else. Basically if I can reproduce it, I can fix it.

If you have something you can send me then I can see if I get the same result. It'd also be handy for you to put-up the debug-console and give me some of the figures and/or provide a screenshot so that I could advise you.

Melv.
#133
02/24/2008 (7:44 pm)
Melv, I just tried Ken's demo before and after the build you sent me and before I had very noticable jitter, and after I didn't have any. Looks like 1 problem down... :)

I've also just sent you my current project's game folder. The jitter there is not as bad as with Ken's demo, but not as smooth as it should be for a breakout game.

Thanks,
Bruno
#134
02/24/2008 (9:40 pm)
@Bruno
It seems we're in the same situation. It makes me feel better not to be the only one xD
Is your CPU a single core (preferably 3/4 year old)?
#135
02/25/2008 (12:45 am)
Its actually a dual core, about a year old (intel).
#136
02/25/2008 (9:14 am)
Bruno,

I'll have a look at it this evening when I get back from work. Thanks for the help!

Melv.
#137
02/25/2008 (3:47 pm)
Interestingly, after doing some profiling on some of the demos provided above on a high-end and low-end machines, there seems to be a dominating feature which I know has cropped-up on the boards before. It could be a red-herring but at the moment looks like a black rock in a field of snow....

On a low-end machine, a demo which merges Kens demos with a level from Ice-Wolf exhibits poor performance but that's because the machine has a low-end GPU. Anyway, on this system the profiler reports that over 77% of the time is spent in "glFinish". Of course, this could just be normal time waiting for rendering to finish and just highlights the slow rendering situation. There have been reports in the past of "glFinish" causing other problems on certain systems.

Now I understand some of the history for calling this but I'm not aware of the current state of thinking on it.

This could well be the cause of jitter in some cases.

Melv.
#138
02/25/2008 (10:00 pm)
Melv, got your email, but I'm at my day job now and wont be able to send the screenshot you asked for until I get home.

Edit: home now, just sent the screenshot and a brief description.
#139
02/26/2008 (8:16 pm)
Just to report that I am working with Benjamin and Bruno to help resolve their particular cases in the hope that it may reveal some other aspect of poor performance in the engine.

I've essentially been doing highly instrumented builds in the hope to catch the culprit.

As always I'll report back on anything substantial that I find.

Melv.
#140
02/28/2008 (8:17 pm)
Melv,

Just a little issue, not involving jitter but a tick related nonetheless. The problem is that in "t2dSceneObject::integrateObject()", the call to "updateWorldLimit()" can change the final position of the object after the tick position has been updated.

My (temporary?) fix is to add one line in "t2dSceneObject::updateWorldLimit()":
// Update Container Config if there was a collision.
       if ( collision ) {

            // Update Container Configuration (not mount-nodes).
            updateSpatialConfig( false );
            getParentPhysics().setPostTickPosition (getParentPhysics().getPosition());   // <----- Add this
       }

Which of course involves creating the function " t2dPhysics::setPostTickPosition()":
//-----------------------------------------------------------------------------
// Set Post Tick Position.
//-----------------------------------------------------------------------------
void t2dPhysics::setPostTickPosition( const t2dVector& position )
{
   // Store Current Tick Position.
   mPostTickPosition = position;
}
Alternately, I was just thinking as I write this, if you don't want a function that can externally change the post tick position, perhaps a function that only updates the post and doesn't update the pre and render tick positions.
//-----------------------------------------------------------------------------
// Update Post Tick Position.
//-----------------------------------------------------------------------------
void t2dPhysics::updatePostTickPosition( void )
{
    // Store Current Tick Position.
   mPostTickPosition = getPosition();
};
I suspect there might be other places where an object's position is changed, perhaps as the result of a collision that might need a similar tweak.

Wow... 141 posts in the thread so far :)

Cheers!

Edit: Fixed updatePostTickPosition()