Optimising Shadow Casting (and other shadow trickery)

Blitz3D Forums/Blitz3D Programming/Optimising Shadow Casting (and other shadow trickery)

Dock(Posted 2003) [#1]
I'm working on a game which uses Swift's Shadow system for the shadow casting, and I'm trying to think of ways to optimise the shadow trickery. I haven't yet done much code yet ^-^; but I'm working through the theory so I can make sure my graphics are suitable for use in the system. What I want to know is how can I reduce the number of polygons used for the shadow calculations.

I'm currently working on a 3000 polygon character, which is quite a lot and I'm aware of the system overhead of calculating shadows. However, many of those polygons will be on the face, and completely excessive for the shadow casting itself.

Is there any way to use an invisible low poly model (or just a low poly head) and have that act as the shadow caster? This would also be ideal for the hands. If I were to make a secondary invisible mesh and tie it to my B3D file (and bones), with a transparent UVMap, would this be possible?

Also, I was wondering about the prospects of casting shadows on to the player model (which is an animated B3D file). Would it be possible to have a planer mapped second set of UV co-ordinates and set that as a shadow receiver. Then move the theoretical invisible receiver along with the player. It would update the shadow received, and the player would have a shadow cast upon it. I realise the planar UV map would probably have to be updated every frame so that the animated model doesn't distort the shadow, and I have no idea whether this is possible. It's all theory :)

Anyone with experience with shadow casting, I'd really appreciate your input.


sswift(Posted 2003) [#2]
Yes, you can hide a model, and still have it cast shadows. So you can have a low poly version of your character, and have that cast the shadows which appear to come from the higher poly character.

Making a transparent UV map might not be a good idea. And it would require modifying the system. It would be better to just make two seperate animated models and syncronize the animation playback.


"Also, I was wondering about the prospects of casting shadows on to the player model (which is an animated B3D file). Would it be possible to have a planer mapped second set of UV co-ordinates and set that as a shadow receiver. Then move the theoretical invisible receiver along with the player. It would update the shadow received, and the player would have a shadow cast upon it. I realise the planar UV map would probably have to be updated every frame so that the animated model doesn't distort the shadow, and I have no idea whether this is possible. It's all theory :)"


Hmmm...

Nope. Won't work.

You would have to update the UV coordinates on the character every frame essentially "planar mapping" them every frame. And to do that you'd need to know where the vertcies are. And to do that you'd have to transform every vertex into the space of the bone which controls it.

And if you're gonna do that, well you might as well just change the shadow system so it can do that and let it do it's own mapping.

The reason I didn't support that is because characters are so high poly it would be slow to update all those vertcies and the trasnformations on top of that would kill it more, and then there's the problem of even KNOWING which bones affect which vertices which would require hand made B3D loader code.


Binary_Moon(Posted 2003) [#3]
sswift - I was under the impression you could cast shadows of any 3d object using your system (including boned b3d files)?

Would it be quicker if people specified a bounding box for players and other moving objects when they specify them as casting shadows? That would save you having to loop through all vertices and save Dock using low res versions of his objects.

The only time I can see this messing things up is if the object animates and part of the object leaves the bounding box. You could just make the box larger than the character to allow for this.

I don't know... I just can't see why the player having a lower poly head would speed anything up since I was under the impression that it was the polygons on the scenery (recievers) that mattered.

Or have I missed the point? (probably)


Dock(Posted 2003) [#4]
Okay cool ^_^ Thanks for the response! I'm very happy about the low polygon character shadow casting, it will certainly make my shadow intensive game idea scale down more. I'll be sure to use HideEntity rather than Entity Alpha 0 or transparent UVmaps.

Okay, thanks for explaining about planar map idea. It makes sense when you explain it. A couple of more questions:

Would it be possible to cast shadows upon a character that was constructed from solid objects with child/parent relationship? (not a deformable mesh). If not, then how do these differ to solid objects?

Secondly... if a model made of parent/child objects shared the same polygon structure as a animated mesh (the same arms and legs, but chopped up so each bone is an object), could the shadow map be projected on to the animated mesh? It would probably look a bit messy around the joint ares, but I'm wondering whether that might be a possible workaround.


sswift(Posted 2003) [#5]
" sswift - I was under the impression you could cast shadows of any 3d object using your system (including boned b3d files)? "

You can. But they cannot RECEIVE shadows.


"Would it be quicker if people specified a bounding box for players and other moving objects when they specify them as casting shadows? That would save you having to loop through all vertices and save Dock using low res versions of his objects."

Nope. My system already generates bounding boxes for every receiver and uses those to cull objects which have no shadows falling on them.

And the polygons in casters are not processed, so the only check I do on those is a distance check to see if they are outside of the range of a light source.


"The only time I can see this messing things up is if the object animates and part of the object leaves the bounding box. You could just make the box larger than the character to allow for this."

Not an issue. Only casters can be "animated". I generate a bounding sphere for them, which is used to determine how large they should be when rendering the shadow map, and that has a small potential for error, but there's a fuge variable in there which you can increase should you run into a problem.


"I don't know... I just can't see why the player having a lower poly head would speed anything up since I was under the impression that it was the polygons on the scenery (recievers) that mattered."

To render a shadow you have to render a view of the object casting the shadow from the view of the light source. Using a lower polygon version of the object could potentially speed that up somewhat if the object has a lot of polygons. I'm not really sure of what the true savings might be though.


"I'll be sure to use HideEntity rather than Entity Alpha 0 or transparent UVmaps." If you have a problem with the shadow not rendering after you do that, lemme know. If I ned to fix something with that, I know it will be trivial to correct.


"Would it be possible to cast shadows upon a character that was constructed from solid objects with child/parent relationship? (not a deformable mesh). If not, then how do these differ to solid objects?"

Yes, you can cast shadows on hierarchial animated meshes, but so few people use them I don't advertise that cause it migth confuse people into thinking vertex animated meshes can have shadows cast onto them, and most people don't use those kinds of meshes.

However, there's one issue with them. You need to make every child cast it's own shadow. This will obviously make things slower, and result in darker areas where the shadow each limb casts overlaps with the shadows of other limbs.

To support casting a single shaodw from such meshes, I would need to rewrite a lot of code, and there would be issues where the system would crash if the model had a pivot or light as one of it's children since Blitz offers no way to tell if an antity is a pivot or a camera or a mesh or a light or any of the other kinds of entities Blitz supports.

So it's really not worth trying to support.

"Secondly... if a model made of parent/child objects shared the same polygon structure as a animated mesh (the same arms and legs, but chopped up so each bone is an object), could the shadow map be projected on to the animated mesh?"

Heh. You really want shadows to cast onto character don't you. :-)

It's not worth it. Shadows are already too costly, and casting shadows onto characters would just be too much. One of the BIG costs of the shadow system is the shadow meshes which are generated, and imagine casting a shadow that covers an entire 1000 polygon character that has to generate a 1000 polygon mesh or TWO every frame. A 1000 polygon room or level is comparably cheap because only a few of the polygons actually have the shadow falling on them.

Anyhow, the answer to your question ithere is still no. :-) You have to create a mesh that meatches the polygons in the mesh which the shadow is cast onto, and you have to know the locations of the vertcies, and set their uv coordinates... I suppose in theory you might be able to somehow generate a segmented model to do this, seeing as Blitz bones only affect one vertex each, so you just divide the model by how the vertex zones are split up... And then you could associate each one of those vertices with the model... That would tell you where the vertcies are. But there's still too many polygons in a character. Would kill the framerate. And it's not the sort of thing which I'd want to implement in the system given how kludgy it is and how few people would use it.


Dock(Posted 2003) [#6]
I don't really want to make a method with a huuuuuge overhead, but if there was some clever trick to manage some sort of shadows then it would really be nice, of course ^_^ Yes it's something which I would especially like in my game, as it's very shadow-centric (I hope you will like how it comes together ^_~)

Another thought I had was of Halo's cubic mapping technique, here: http://www.blitzbasic.com/bbs/posts.php?topic=21569
Could a shadow be cast on to a flat square area (a hidden plane perhaps) and then cast on to the object? For accurate shadows you would need to reset the face normals of the lightmap with each frame, but it would potentially work (although inaccurately) even if you didn't reset the normals. Might this be possible for simple shadow casting such as shadows from leafy branches in trees? The character will only be walking, so the distortion from walking ought not to be too huge.


sswift(Posted 2003) [#7]
If/when mark implements cubic mapping, that which you desire may become possible.

You would create a cube, project shadows onto it without any falloff other then a simple distance based falloff, and then render a cubic map of that cube from the inside.

Not sure how well it would work though. Might have some issues. May need to project shadows onto a low polygons sphere and cubic map from inside that intead.

Wouldn't be very fast. You would have to render 2-4x as many shadow maps to shadow an entity like this, and rendeirng the shadow maps is one of the most expensive operations.