Render tweening and stutter/jerkiness

Blitz3D Forums/Blitz3D Programming/Render tweening and stutter/jerkiness

Yasha(Posted 2011) [#1]
So, I have an embarrassingly n00bish question...

Who here is using render tweening? Of those, who has managed to get it to work as advertised and provide "silky smooth" screen updates? 'Cause I'm having difficulty with this.

The first thing I tried is the castle demo in Samples\mak. It seems like an odd choice for a demo of something supposed to smooth updates, because I found it actually really jerky: once every second (it's quite regular) the demo seems to skip a frame and jerk to the next position. It's unsettling and gives me a headache; certainly not an appropriate effect for a released product!

I've played with the samples a lot over the years, so I re-downloaded it, just to be sure; the stutter definitely appears in Mark's original version. It's not easy to spot (but still present) in windowed mode, but in fullscreen it's quite obvious.

Anyway, I never used that code as it didn't quite suit my purposes. I came up with a slightly different version, based on the famous Fix Your Timestep! article (chopped this out of the middle of my program):


Local renderTime = Floor(1000.0 / ProgSettings\DrawRate), updateTime# = 1000.0 / ProgSettings\UpdateRate
Local cTime = MilliSecs(), accum#;, limited = True
Local ShowDebugInfo = False, FPScount, FPStime, FPSframes		;Debug info

Global RenderTween# = 1.0		;Global for reasons not shown here


While Not KeyDown(1)		;Outermost main loop - rendering and all secondary functions
	accum = accum + (MilliSecs() - cTime)		;Accumulator for update loop
	cTime = MilliSecs()		;"Official" start of loop
	
	
	;[Block] Update loop (for render tweening) - all movement, input and update happens within this one
	While accum >= updateTime
		CaptureWorld
		
		;Place updates here
		
		accum = accum - updateTime
	Wend
	RenderTween = accum / updateTime		;[End block]
	
	
	;Draw everything that needs drawing (mostly 2D stuff)
	
	
	RenderWorld RenderTween		;...and render it
	
	If ProgSettings\LimiterOn Then Delay (renderTime - (MilliSecs() - cTime)) - 1		;Free spare CPU time
	If ProgSettings\VSync Then VWait
	Flip False
Wend


It's not as obvious, but the jerks are also less regular (I'm not sure - is that better or worse?). Still nowhere near good enough for release.

I'm sure I must be missing something obvious here, as surely nobody would use render tweening if it normally gave the kind of results I'm getting. Does the castle demo work correctly for other people? Maybe it's my computer?

Lucky for me I'm designing my program for a specific machine, so I can always use a fixed update/render rate for the moment. I don't want to do that though as it would hurt the inevitable port to general PC release... and I want to understand why this is going wrong! It's really ticking me off...


---

I also have the feeling that there may be a bug with render CaptureWorld and deactivated cameras - has anyone experienced any problems with anything like that? I do hope it's not a B3D issue.


Ross C(Posted 2011) [#2]
I have never used render tweening. I just use a delta value and adjust everything based on how long a frame takes.


Yasha(Posted 2011) [#3]
That would probably be adequate, but I don't want to do it for two reasons:

1) Delta timing requires modifying your movement code throughout the program, which is rather like hard work (and a pain to maintain/refactor). Tweening is already built in to Blitz3D, and shouldn't require much more modification than an elaborate loop code.

2) For reasons explained in the aforementioned article, delta timing isn't really appropriate for anything requiring precision or consistency as it's much harder to get the maths right (e.g. anything involving physics).

Here's an example of that algorithm in use, dug out of my old projects folder (I am far too lazy to write a new one):



(The crappy attempt at a physics engine "justifies" the need for fixed-rate logic. The crappy coding style is just a younger, even more insufferable version of me... ugh.)

Anyway, I find that the effect is pretty obvious if you push the cube to the rear of the area and drive it back and forth across the screen. It has time to "stutter" once or twice per pass.

If this (and the castle demo) looks smooth to other people, perhaps there's something wrong with my computer. It strikes me as odd that neither well-known algorithm should work correctly!

Last edited 2011


Rroff(Posted 2011) [#4]
I've never noticed render tweening to be jerky except when I've messed something up - I do make sure I use 30Hz gamelogic updates tho rather than 20 or a higher value.


Adam Novagen(Posted 2011) [#5]
I've never noticed jerkiness, but I have noticed that "snap-to" actions get interpolated; to clarify, a call of PositionEntity() to move something from one point to another ordinarily just PUTS it at the new location. With render tweening, it can often be seen - only in a single frame, mind - moving through a waypoint. It doesn't appear to move per se, but it gives an annoying flickering impression.


RifRaf(Posted 2011) [#6]
It can be caused by a code execution delay without updating the rendertween value..

for example, a pause menu. If in the pause function you dont continue to update tweening timing, when you unpause you will get a big "jerk" or even a rendering lockup because of the timing.


Yasha(Posted 2011) [#7]
I think that I have worked this out, and that I have been quite stupid...

In case nobody looked at the code (both Mark's castle and my demo above), I've been testing these with VSync enabled (Flip True in both demos; VWait in my real application).

All I had to do to make the funny effect go away was try it with no VSync of either kind (you can see the difference quite easily by trying both ways with the demo posted above). I guess that render tweening isn't intended to be used alongside other kinds of frame limiter codes as well? (I probably need to fine-tune the Delay line so that it doesn't interfere with the tweening too.)

So that also means that Mark's code is correct after all (that old mantra we see every so often on this site still holds: "trust Mark's code!"). Slightly odd choice for the demo of it to have Flip True on, but whatever.

I could be wrong. I've been staring at that darn castle demo for about three hours now. My eyes hurt.

(How I found this out: by adding a simple WaitTimer to the castle demo in the hopes that I could slow the render FPS down and catch the effect by eye more easily, to match it up with crap spewed to the debug console every frame... and instead noticed it made the effect worse. Hence, a connection to timing code. Then thought to try VSync.)


Rroff(Posted 2011) [#8]
Could do something like with idtech5 where it analyses performance and when the framerate is slowing down it doesn't wait for the vertical scanline to reset before rendering the frame, by doing something similiar but also adjusting so that tween updates aren't delayed it could produce smoother performance in both regards (also less input lag) and only minimal tearing.

Last edited 2011