Q: to those who use tweening with my shadow system

Blitz3D Forums/Blitz3D Programming/Q: to those who use tweening with my shadow system

sswift(Posted 2004) [#1]
Someone asked me this question recently:

"Hmmmm, I put the 'update_shadows' command right before the 'renderworld' outside of any tweening loop but I still get the jittering. If I just use renderworld without the tweening it looks fine though so it's definelty something to do with the tweening.Any other ideas on what may be causing the problem? It looks just like the tweening anomaly where you want to make a object teleport but the tweening draws the object between the start and end points making it look like it moved very fast instead. Excpet the shadow looks like it's rotating back and forth 5 dgrees very fast."


Now, I'm positive that this is not a bug with the shadow system, because I _KNOW_ people have used tweening with my shadow system before. But I'm not sure what _is_ causing it. I'm not very familiar with render tweening. I hate it. :-) It's complicated and causes problems like these all the time.

So I thought I'd ask here, to see if anyone who has used render tweening with my system has had an issue like this and corrected it by tweaking their tweening loop somehow?

The only things the tweening code could affect would be the casters, or the receivers, but not the shadow meshes themselves... since they never actually move. And I'm pretty sure from his description of the problem that it's not the receivers. Shadows would be poking into geometry and stuff if he was moving receivers around and those weren't being updated probperly.

So that leaves the casters.

Each frame I copy the caster in it's current frame of animation, paint it black, and use that to generate the shadow. Then it is deleted. There is seemingly no way tweening could affect this, but somehow it apparently is.

I'm guessing his tweening loop is messed up in some way, but I don't know how. I've asked him to send me the code to his main loop so I can look at it though.


Gabriel(Posted 2004) [#2]
I use tweening with your shadow system and the two get along perfectly. I did initially have the same problem he describes, because my tweening loop was messed up, as you say, but that was easily solved.

My tween loop looks something like this :


; SETUP TWEENING
	
TWEEN_period=1000/TWEEN_TargetFPS
TWEEN_time=MilliSecs()-TWEEN_period

GameOver=0

Repeat

   ; DO TWEENING

   Repeat
      TWEEN_elapsed=MilliSecs()-TWEEN_time
   Until TWEEN_elapsed
	
   TWEEN_ticks=TWEEN_elapsed/TWEEN_period
   TWEEN_tween#=Float(TWEEN_elapsed Mod TWEEN_period)/Float(TWEEN_period)
	
   For TWEEN_k=1 To TWEEN_ticks

      TWEEN_time=TWEEN_time+TWEEN_period
      If TWEEN_k=TWEEN_ticks Then CaptureWorld  

      ; UPDATE GAME

      UpdateGame()

      UpdateWorld

   Next
   
   ; RENDER STUFF

   Update_Shadows(MainCamera)
   UpdateParticles

   RenderWorld TWEEN_tween#
   Flip
Until GameOver


I used this for Tennis Babes and I'm using it now for Bowling Babes. I don't see how it could possibly go wrong as long as the tweening loop is good ( and mine is perfect because I stole it from someone much cleverer than me ;) ) and Update_Shadows is only called outside of the for..next loop.


Rob(Posted 2004) [#3]
Sswift:

PositionMesh will not cause jitters with tweening.
PositionEntity will cause jitters when tweening.

If you rely on PositionEntity it might be worth testing.


AntonyWells(Posted 2004) [#4]
Another way might be to find the 'blitz is hacked' thread and poke the x,y,z values directly into the entity, so it avoids any tweeny by blitz. I mean blitz has to keep it's current position of each entity somewhere..it'll be in that structure too.


Pongo(Posted 2004) [#5]
Don't know if this is related or not, but I use "setanimtime" quite a bit and it is usually on a number between frames. I was having shadow update issues until I changed the following variable:

Texture_Angle_Epsilon# = .5

After setting that to a low values things worked flawlessly for me.


sswift(Posted 2004) [#6]
Uh... SetAnimTime and Texture_Angle_Epsilon have nothing to do with eachother. :-) So you probably chnaged something else to fix your problem.

Texture_Angle_Epsilon is a value which defines how much the angle between the light and the shadow caster needs to change before the system re-renders the shadow texture.

Ie, a shadow rendered directly above and object, and a shadow rendered directly behind an object are seperated by 90 degrees.

Also, a shadow rendered from above an object, and a shadow rendered from above an object which has been pitched forward by 90 degrees, are also seperated by 90 degrees.

Add these two transforms, and you have a difference of 180 degrees.

0.5 here means half a degree of change total. So if the angle between light and object only changes by half a degree, meaning the outline the shadow represents hasn't changed much, then the shadow is not re-rendered that frame. But if the angle between them changes by 0.6 degrees, then it is re-rendered.

All entities that animate force their shadows to be re-rendered every frame. They cannot take advantage of those optimization. There is no way to know how much their outline has changed from one frame to the next.

...

Hm...

Something occurs to me though. If you do not set your entity to be animating, and only change it's animation frame with set anim time, assuming that works... Then the system may not know that the entity is animating, and it would only update the shadow when the angle between the light and caster has changed sufficiently. That would mean that if you just kept the entity in one spot with a static light source that is unmoving, unless you set epsilon to 0, the shadow would never match the animation.

But that ASSUMES that the Blitz animating() command will still return false if you have just changed the animtime, and that changing the animtime will work at all if if the entity is not animating. If you have the entity set to animate but set it's animtime every frame, then things should work. But if you ahve the entity not animating and set animtime every frame, assuming that works in Blitz, then you might have the problem you described with the shadow animation being "jerky".

So I guess episolon and setanimtime may have something to do with eachother after all. I never considered someone would animate an entity without actually turning on animation. Even with setanimtime.


James(Posted 2004) [#7]
Well, I'm the guy having problems with my shadows. Here's my main loop:

Const gameFPS=30
Const gamePeriod=1000/gameFPS
Global gameTime=MilliSecs()-gamePeriod


;Main
While gameQuit=0
	;Game FPS
	Repeat
		gameElapsed=MilliSecs()-gameTime
	Until gameElapsed
	;How many 'frames' have elapsed
	gameTicks=gameElapsed/gamePeriod
	;Fractional remainder
	tween#=Float(gameElapsed Mod gamePeriod)/Float(gamePeriod)
	;Game updates
	For tweenK=1 To gameTicks
		gameTime=gameTime+gamePeriod
		If tweenK=gameTicks Then
			CaptureWorld
		EndIf
		updateGame()
		updatePlayer(playIndex)
		RunCollisionBlitz()
		UpdateWorld
	Next
	;shadows must be updated just before renderworld
	Update_Shadows(pcam)
	;Render
	RenderWorld tween#
	Flip
	Cls
Wend
End


It's almost identical to Sybixsus'. I'm not animating anything right now. Just moving a .b3d box and shadow mesh exported from max using 'moveEntity'. If I 'renderworld' without tween it looks just fine. I have tried turning collisions and any extra processes off but nothing helps. Anybody have any ides? Is there something wrong with my loop that I can't see? Thanks for looking.

James


Pongo(Posted 2004) [#8]
All I know is that it did the trick for me. What you said sounds right, and that value DEFINATELY has an effect. In my game I don't use animate at all, and set the animtime every time through so I can have control over forward/back at any speed I want. (you have seen this in action I believe,... the BigTop Bob game test)


I can send you my code if you want to check it out.

Anyways, I thought it might be a similar thing because like with tweening you are accessing a position that is interpolated.


SabataRH(Posted 2004) [#9]
I used your shadow system and frame tweening in Riker2, but has been quite awhil enow... can't recall what i did to make it work correctly.


sswift(Posted 2004) [#10]
Would these commands be affected by frame tweening?

	; Position the light pivot where the light is in the world.
			PositionEntity Light_Pivot, Light_X#, Light_Y#, Light_Z#, True

			; Point light_pivot at the caster.								
			PointEntity Light_Pivot, ThisCaster\Entity

			; Calculate the normal of the light's ray in world space.
			; We use this normal to calculate how to project the points in the world onto the light's plane.
			;
			; Optimization note: 
			; The normal of the caster plane will be the same as this normal, so we will not need to calculate
			; this normal.
			; (A, B, C) will be the normal of the plane.
			TFormNormal 0, 0, 1, Light_Pivot, 0
			Light_NX# = TFormedX#()
			Light_NY# = TFormedY#()
			Light_NZ# = TFormedZ#()

					; Top left.
					TFormPoint -ThisCaster\Radius#, ThisCaster\Radius#, 0, Light_Pivot, 0
					X1# = TFormedX#()
					Y1# = TFormedY#()
					Z1# = TFormedZ#()



If these are not affected by frame tweening then I am at a loss to explain this, because those are basically the only commands that I have currently executing that could theoretically be affected by tweening, and I'm still getting the effect. I have taken his code and modified it so it uses texture shadows and not dynamic shadows, so I know that none of the code that generates dynamic shadows is at fault. ... But that was my most likely suspect. Now that I cannot suspect that I don't know what to suspect.

I would not have thought these commands would be affected by tweening, but if they are not, then I'm out of ideas. There are few places in my code where I deal with entities, and without the shadow generation stuff, that's pretty much it.


SabataRH(Posted 2004) [#11]
Well,
PositionEntity Light_Pivot, Light_X#, Light_Y#, Light_Z#, True
is effected by tweening, but I don't think Tforms are.. since tform updates to the embeded coordinates (non tween location) - it should work fine.

Might I suggest moving the 'Update_Shadows(MainCamera)' call in to the tween loop itself? just to see what happens. Since the mesh calls are being moved within the tween itself I would think it's only natural you'd have to update the shadow system to match.. Hypathetically.


sswift(Posted 2004) [#12]
"Might I suggest moving the 'Update_Shadows(MainCamera)' call in to the tween loop itself?"

Already tried that, in several places. Has no effect.


skidracer(Posted 2004) [#13]
Very close lights may show up the fact the shadow routine is using untweened transformations. You may want to test a scene where the distance from light to rotating object is much less than object to shadow collision. (edit - this on second reading doesn't sound that logical).

Also a good way to test tweening is to lower the GameFPS to 1 update per second.

I don't quite understand why a shadow system needs to be camera dependent but if it is I would also examine exactly how the camera and parents are being moved also. I would start by putting the UpdatePlayer (if it is an FPS camera) before the CaptureWorld...


sswift(Posted 2004) [#14]
The shadow system needs the main camera passed to it so that it can hide it before it renders shadows with it's own camera. It never moves the main camera.

I'll try reducing the fps and see if that has any affect.


sswift(Posted 2004) [#15]
Hm... Changing the FPS to 1 shows that what the problem really is is that the shadow is moving in coarse steps from one location to the next.

I think I may be starting to understand what is causing the behavior.

Let's say that I move an entity from point A to point B.


A -------------------- B

With render tween, the entity will be rendered at every position marked by a *.

A ---*-----*------*--- B

But when I get the position of the entity in Blitz, so I can point the light source at it and render the shadow, the shadow system does not see the object at the position marked by the *'s. It only sees it at A or B.

When you use tween with renderworld, you are usually rendering at one of the * locations. So the shadow lags behind until you reach B, and then it catches up suddenly because you've updated the entity's location. But when you update the entity's location, that means the shadow is leading it. So the shadow waits there till the entity catches up, and then it jumps ahead again. So actually it's not lagging behind... it's leading the entity.


There is no way I can fix this problem within the shadow system itself. I have no way of knowing if tweening is enabled, or the tweened locations of entites, and to allow you to manage that through a tweening system built into the system would make the system much more complicated.

This seems like a pretty major oversight in the Blitz tweening system... And nobody has encountered this problem before? It seems to me that it would affect skies being centered on cameras... And fake shadows placed beneath players... unless they are parented to the camera, or player. But if you parent a sky to a camera then it would rotate wit the camera... So.... have people been creating pivots which they parent the sky and camera to so the camera can pivot independently, but still move with the sky?

I hate tweening!


Michael Reitzenstein(Posted 2004) [#16]
sswift, in all of those examples, the object is tweened in the same way as the 'parent' if you give them the same EntityX every frame.


sswift(Posted 2004) [#17]
"sswift, in all of those examples, the object is tweened in the same way as the 'parent' if you give them the same EntityX every frame."


Okay, I can see how that would be true... But what if all your entities used shadows made from quads contained within a single surface, rather than individual entities? THEN you'd have the same issue...

I'm sure there are a hundred other things which would be affected by this that I just haven't thought of yet. Pretty much any mesh-based animation that depends on the location of an entity... For example, a single surface particle effect might be effected by this if the effect is designed to follow an entity but the emitter itself does not move. And how about contrails?

It also occurs to me that if I had made a point light system that works like Quake, ie, dynamic lightmaps... that this would probably have also been an issue there as well.

Oh tweening, how I despise thee!

It's amazing nobody ever pointed out this issue before now. My system has been out for roughly two years now I think.


Michael Reitzenstein(Posted 2004) [#18]
Single surface tweening is indeed a bit of a bitch.


Pongo(Posted 2004) [#19]
Did you try the Texture_Angle_Epsilon# thing? As I was saying before, when I was using setanimtime, the shadow was only updating on keyframes, and not between them until I set this value low enough.

Your description above with the A-B and the *'s was Exactly what was happening to me before I set the value down to a low number. If what you say is that it forces blitz to re-evaluate the mesh, then that is what you need to do anyway,... correct?


sswift(Posted 2004) [#20]
Pongo:
Yes I tried that, before I knew what was occuring, and no, it had no efffect.


Jeroen(Posted 2004) [#21]
I removed your shadow system from my game after the render tweening problems described above. Sorry I can't help you with it.


Bot Builder(Posted 2004) [#22]
This is why you use delta timing rather than render tweening. You can have things unaffected by tweening, and you have complete control over how it works. For instance, if you are worried about delta timing making the object move erraticly (if you have collisions or speed sensitive processes), you can have it move part way, then another part, etc.


James(Posted 2004) [#23]
Well, for those of you that say you have both tweening and swifts shadows working. It would be much appreciated if you would show us how you got it to work without the jittering.

James


Rhyolite(Posted 2004) [#24]
I did some intitial tests using tweening and had no problems. However, objects were moving slowly and I was updating my world (which included the 'CaptureWorld' and other tweening code) 25 times a second.

Unfortunatly, I no longer use Swifts Shadow System as it proved too slow once I had more than a couple of casters AND recievers in a fairly high poly world and will be using fake shadows instead :o( Shame as I liked it, but I did learn a lot looking through the code ;o)

Thinking about it (but not very clearly as just got up!), I was surprised I had such serious speed problems compared to the demo. Could this be because of tweening also? I am pretty sure I was UpdatingShadows in my update world code which ran 25 times a second, not in my Renderworld loop which could run much faster. I think I even tried updating less frequently.

Another thought, would speed be effected by distance? I do NOT mean a slow down because more recievers are in range of casters/lights etc, but 'actual' distance??? Cant think of any reason why, but my shadows were being cast over fairly large distances (perhaps 1000 blitz units) onto 1 or 2 recievers (there was a lot of 'empty space' in my game)?

Ooops, going off topic here - sorry!

Rhy Out


sswift(Posted 2004) [#25]
Distance has no effect on speed.

You should never update the shadows if you are not going to then immediately do a renderworld. Ie, if you are going to update physics twice during a frame, you should only update the shadows on the second physics update. The shaodws only need to be updated when you will actually see the change. I do not know if how you had things set up was affecting the speed adversely or not, I'd have to see what you did.


Rhyolite(Posted 2004) [#26]
My code would do perhaps two or three RenderWorlds for every update of physics (which included shadows) when running 'ok'. But if the frame rate dropped below the physics update rate then you might get multiple physics updates for each RenderWorld, but dropping below 25 FPS is already becoming unacceptable performance (for my game anyway). I think I even tried only updating shadows every other physics update, so that would be something like one shadow update followed by four or five renderworlds!

If would love to know if I am doing something wrong? If I can find my original test code I might post it/send it?

I would point out that your shadow system worked very well when used with limited casters, recievers and lights - which you have always made very clear in your documentation anyway. I would love to use it as the effect was very nice :o) Would it be possible to build in more approximations to speed up the code with a slight loss in quality/precision?

Rhy Out


Bouncer(Posted 2004) [#27]
I did my own tweening for my single surface particle system... and it works great with blitzes entity tweening . You just have to tween manually.

Just store old and new co-ordinate and use the current tween value to get the desired position at render time for each particle/shadow/anything in single surface...


Rhyolite(Posted 2004) [#28]
@Bouncer: Just so I understand correctly, I assume you do NOT use RenderWorld(tween) but calculate a tween value and then manualy position your objects? I need to refresh myself on this whole topic again and check if I am still happy using Blitz tweening for my current game (and perhaps have another go using Swifts Shadows), but is not the method you described usualy reffered to as 'Delta Timing'?

Rhy Out


Bouncer(Posted 2004) [#29]
I use renderWorld... but I tween my particles manually. Because they are on single surface they don't obviously tween automatically.


Rhyolite(Posted 2004) [#30]
Ah, got it - sorry I was slow. Renderworld only moves entities and your particles are all a single entity (surface). Thanks for clearing that up for me :o)

Rhy Out