[solved] Why so choppy with higher fps?

katzenjoghurt

06-10-2007 17:15:23

Hi again. :D

It's me again ... noooo stayy! Please!! :shock:


Hm... I'm wondering why rendering is so choppy with higher fps.

I recorded two videos to explain.

This one is recorded with 60fps:

http://wwwstud.ira.uka.de/~s_walser/choppy60.avi

(reincoding of the video file killed a lot of the choppyness but I think it's still visible)

And this one with 30fps:

http://wwwstud.ira.uka.de/~s_walser/smooth30.avi

(though there is also this noticeable jittering when the force is applied the second time...)


No fancy things happening in the background though.


It's just a ...

myBodyX05 = mScene->createBody("edelguppy.mesh",new NxOgre::CubeShape(10,10,10),Vector3(100,340.5,-650), "mass: 10");

in the scene setup and a...


if (passedTime>=5.0)
{
myBodyX05->addForce(Vector3 (-30,0,0), NX_VELOCITY_CHANGE);
passedTime=0;
}


...in the framelistener.


:cry:

betajaen

06-10-2007 18:18:44

It may be down to the precision of the float or the inaccuracy of the windows timer. Is your Scene using a fixed or variable iterator?

katzenjoghurt

06-10-2007 19:14:56

ahhh ... you know your wrapper... :D

It was indeed set to

mScene = mWorld->createScene("Main", sceneMgr, "gravity: yes, floor: yes, time-step-method: fixed");

after changing to

mScene = mWorld->createScene("Main", sceneMgr, "gravity: yes, floor: yes, time-step-method: variable");

everything's fine.

--

I blindly copied this line (not knowing what the parameter meant) from somewhere (thought it was from the wiki... but the time-step-methos isn't set up at all there) ...

Thx once more, betajaen. You rock! :D

betajaen

06-10-2007 20:17:38

Yes. Yes I do. ;)

katzenjoghurt

07-10-2007 15:21:48

Mhhhh... let's test it... :P

Now with time-step-method: variable everything is no longer deterministic anymore... it's dependent on the framerate... :oops:

http://wwwstud.ira.uka.de/~s_walser/fishrace_25fps.avi

vs.

http://wwwstud.ira.uka.de/~s_walser/fishrace_100fps.avi

There is also still this jitter right at the beginning - no matter if I start the fishes 10seconds sooner or later ... yet it seems to wear off after some time.

I also tried async as time-step-method .... but it started jittering all the time again.

I guess I need to set up the timesteps properly via the Scenes Scene Controller?
But how?

Loockas

07-10-2007 15:52:04

Hi, I have the same problem with jittering. No matter if I set the time-step-method to variable, there is a choppy animation of my moving ball. Moreover, I have a camera attached to the ball so the effect is really irritating by fast speeds..

@katzenjoghurt: how do you set a constant fps?

katzenjoghurt

07-10-2007 16:01:53

@katzenjoghurt: how do you set a constant fps?

I set the fps up by the recording tool.

katzenjoghurt

09-10-2007 19:19:17

Hmmm... after looking in the NxOgre sources and trying to play around with Iteration parameters I ended up with a simple...


mScene = mWorld->createScene("Main", sceneMgr, "gravity: yes, floor: yes, time-step-method: fixed");

...

bool AppFrameListener::frameStarted(const FrameEvent& evt)
{

mScene->simulate(evt.timeSinceLastFrame);
mScene->render(evt.timeSinceLastFrame);
...



And everything seems to be okay now ... no matter if 312.23 or 60 or 40 something fps ... my test objects always end up with the same yaw after applying a torque to them ... and the jittering is gone.

Strange enough I didn't see any frame drop...

Hum... might also be just some trick of NxOgre who is doing all sorts of nasty things to me today anyway.

betajaen

09-10-2007 19:43:43

No! No! That's a really really bad way of doing it.

See if you have "NX_RENDER_IN_FRAMESTARTED" in NxOgreStable.h (and set it to 1). If not, you'll have to use a custom scene controller.

Otherwise; You can wait until the next version of NxOgre, which has that flag.

katzenjoghurt

09-10-2007 19:49:38

I knew it was bad... it had a cheesy touch ... but at least it did something.
Though... hum...

Hum... the flag was there ... and it was already set to 1.

#define NX_RENDER_IN_FRAMESTARTED 1

Hum...


edit:
Ahh... you wrote there:

// When a framelistener is bound to the PhysXDriver, it will call render scene
// at the beginning of the frame, rather than the end.
// 0 - Render at the end of the frame, 1 - Render at the beginning of the frame.


Hmmm.. how do I do that? *duck*

betajaen

09-10-2007 19:55:54

I don't know why your changes work, and the flag doesn't. It's the same thing.

katzenjoghurt

09-10-2007 20:02:14

Did you see the edit above?
I didn't link my frame listener in any way to NxOgre ... (and I got no idea how I should.)

betajaen

09-10-2007 20:17:58

Well it's already set. It uses a compiler macro to move the render call at frameStarted and not do it at frameEnded.

frameStarted/Ended being in PhysXDriver, which calls World and the Character Controller system (and other things) on frame events.

katzenjoghurt

09-10-2007 20:48:51

Ahh... I see.


### from NxOgrePhysXDriver.cpp

bool PhysXDriver::frameStarted(const Ogre::FrameEvent& evt) {
simulate(evt.timeSinceLastFrame);
#if (NX_RENDER_IN_FRAMESTARTED == 1)
render(evt.timeSinceLastFrame);
#endif
return true;
}


I definitely need to call them both ... simulate() and render() or the jittering won't go away. No matter if I call them via mScene or mWorld though. So it wasn't a matter of the flag.

Hm... yet nothing bad should happen if I call these two methods (again)... should it?

And... well ... you don't need to answer if you're annoyed (really!) but ... my curiosity demands me to ask. :D Why should PhysXDriver::frameStarted() be called when MY frameStarted is called (or a new frame event happens)? I really don't get the trick...

betajaen

09-10-2007 21:28:02

If you call mScene->render/simulate manually then the scene is simulated and rendered twice in the frame.

You could do this though; mPhysXDriver->simulate(time), mPhysXDriver->render(time).

katzenjoghurt

09-10-2007 22:59:27

Well ... yeah ... but it seems I've got no choice.

Thx, betajaen.

betajaen

09-10-2007 23:16:16

Usually its better to control NxOgre yourself. Like with most automatic things with NxOgre it's a curtsey.

I'd assume you'd have some timer system that would periodically update various parts of your framework; Audio, AI, etc. Disabling the framelistener and putting NxOgre on that list just makes things neat.

katzenjoghurt

10-10-2007 09:04:19

Actually my "timing system" consists of multiplying everything that's time dependent with evt.timeSinceLastFrame or putting a corresponding function in frameStarted(). :P Grrreat magician!

Thx for the tip... I made a notice to disable NxOgre's updating in case of frame drops. Can't await the next version (Convex shapeeeees!) ... and I'd surely forget to disable again after updating to .39. :D

betajaen

10-10-2007 09:33:00

Convex Shapes are already in my friend. '39 Just makes it a lot neater and faster to work with.

katzenjoghurt

10-10-2007 09:44:07

Oops?

Then I must have made a big mistake.... tried to load one in. (actually after a testing row I ended up with a simple .mesh cube made in 3d max) and nothing happened... no collision.

But I think I didn't get the idea of cooking yet.

I'll try again... :)

betajaen

10-10-2007 10:42:46

Try "convex1.mesh" that comes with Cake. It's the baseline mesh I use for Convex shapes. If that works, Convex Shapes works.