What's the best solution for real-time shadows?

Blitz3D Forums/Blitz3D Userlibs/What's the best solution for real-time shadows?

JustLuke(Posted 2006) [#1]
So what is the best solution (in terms of the balance between quality and performance) for generating real-time shadows? Ideally, it would works for both static and animated models, and it *must* be fairly simple to use. Some sort of userlib or system that I can just "plug in" to my code would be great.

Any suggestions?


Stevie G(Posted 2006) [#2]
You could try the SSwift's Shadow System, very cheap and loads of optimisation options by the looks of it.

Look for any post by Sswift and it'll be in his sig.

Stevie


bytecode77(Posted 2006) [#3]
check out this:
http://www.blitzbasic.com/Community/posts.php?topic=62378
by me and DareDevil :)

this is not for use yet, but if you want to buy any shadow system, dont buy swift. buy andreymans stencil lib!


Ricky Smith(Posted 2006) [#4]
sswift's shadow system is very good- supports animated meshes and the .b3d format.


sswift(Posted 2006) [#5]
Devil's shadow system doesn't support animated meshes.

My shadow system doesn't support casting shadows from level geometry very well. You can cast shadows from buildings and trees, but you can't make a torch light a room and cast shadows in the areas the shadows can't reach around a corner.

And Devil's doesn't support transparency maps, so it can't cast shadows from trees that look good.

If you need dynamic shadows from everything, you'll probably need both systems. If your levels are lightmapped, then you'll probably only need mine for the characters.

I don't know who this anreyman is or what his stencil lib can do but as far as I know no stencil lib anyone has done for Blitz can cast shadows from animated characters.


sigi(Posted 2006) [#6]
Andreyman`s System can do this.(Shadows with animated Characters.)


Mike0101(Posted 2006) [#7]
Andreyman's system is buggy and he does not answer


visionastral(Posted 2007) [#8]
I have tested both devil's and swift's shadow systems and I find swift's much more game oriented.
I would use devil's system for demo purposes because it works very well with geometry and you don't really have to worry about the shadows (it's full automatic) and it's well implemented and optimised.
But there are some problems with the shade side of the objects showing non smoothed poligons.
Another serious problem is you can't have lots of poligons in your scene because it will simply crash because a blitz's memory overflow. This shadow system creates a projective mesh of the original geometry and thus multiply the number of poligons in the scene for every object who cast a shadow.
Only 1 light is supported by the system and implementing 2 would be dificult.
A perceptual problem of the stencil shadows technique is the extreme sharpness of it. It would be ok for space related scenes but too opressive for daylight and indoors scenes, were it does an opressing feeling like in doom3 (even brightning the ambient, it's about the sharpness of the shadows).
For shadows to render a natural feeling I know about only 2 techniques: Shadow mapping and Area Shadows.
No one has made area shadows in realtime as far as I know, it is used for 3D renders for stuff like FinalFantasy.

Shadow Mapping technique consist in taking a snapshot from the light's point of view and use it to map a shadow texture over the objects who receive it.

Stencil Shadows technique make a 3d mesh of the shadow (really volumetric) and uses stencil buffer and z-buffer operations to discard all the volume except the intersection between the shadow mesh and the receiver mesh. In fact it's a technique to make visible only the intersection of the 2 objects.

Shadow mapping can't be done in blitz3D by itself because the lenguage don't let you take a snapshot of the Z-buffer and store it in a buffer. I don't know if it could be done thru an external dll.

Stencil Shadows can be done using an ecternal dll for controling the stencil buffer status and the z-buffer operations between it and the stencil buffer, but it forces you to make 4 or 5 renders for a sigle image. (this is because Blitz3D limitations, in opengl it can be done easely and much more quickly)

And here comes the swift shadow system wich is an hibrid shadow mapper very well implemented and fast.
(I won't explain it for respect to swift)
It don't have the speed of a 100% shadow mapping but in return it have a lot of good things like the translucent shadows and the control over every shadow projected.
The main problem of this system is the overlapping of shadows: 2 objects projecting a shadow over each other will have their shadows overlapping and darkening the ground double in the zone they overlap (making the zone of overlap black instead of just dark, for example).

Allthought I bought swift's system and i'm very happy with it because you gain 100% control over each shadow so you can adjust the details to make a good result and high perf.
Another advantages of swift's system over the devil system is: you can generate new objects in realtime who cast shadows, shadows are as smooth as you like and much more important, you can make as many lights as you want (but it multiply the render time) and you can spread lights with ranges of action araound your level in order to affect the characters by proximity, so if your character is into the range of a light, the shadow system will calculate the shadow, else not.

I actually use a custom version of Swift's system and I am very pleased with it's code, very very well commented, something that must be said because it enables you to make changes in the code in order to match your purposes.

Devil Shadow System is an impressive shadow generator, it works very well and most important, it is free and comes with the source!
Thank you very much Devils Child and Daredevil for making quality functions and distribute them freely.

I prefer swift system because of flexibility, control and customizable. Devil shadow system is much more rigid, but it's because the stencil technique, not because the coders.

Allthought, I will surely use both system together but for game purposes I think Swift's is more convenient.

Thank you both for making usefull and great quality code for the comunity. :-)

Please excuse my english. :-b


Warren(Posted 2007) [#9]
Another vote for Swift's. It's easy to use and he actually answers email.


bytecode77(Posted 2007) [#10]
nothing is better than a build-in-shadow-system. its better, because you have controls about everything. thats why it might be better to write a 3d engine right from the top :)


visionastral(Posted 2007) [#11]
you're right Devils Child, but in those times we live, you have to make the choice:
You make an engine OR you make the game
unless you have a big team an split it in 2: one group who actually codes and another who makes the game! (that's the best choise , for sure! look at ID or Epic games...)

Blitz3D has limitations, a lot... (don't have access to the z-buffer or the stencil buffer is really a limitation actually... stencil buffer was implemented in DX 6! and z-buffer was present since DX 1!)

But it have really good things like you don't have to write 500 lines of code only to declare your window, deal with direct input and free all this stuff to exit...
That's why I apreciate Blitz3D, and because all of this is integrated in one big package without issues between modules.
It's about simplicity, and simplicity has a price!
Else, go write in Visual C, you will have full power, that's for sure! You will do things faster than blitz with it and OpenGL and more technically impressive stuff like Pixel Shader and the like. But you will take far more time to do simple things like MoveEntity keeping the direction of an entity or the RenderTween....
It's amazing how much time you can spend doing things that actually haven't nothing to do with the main purpose of your aplication!
I hate that! :-b

That's why Blitz3D, even limited, is welcome.

:-)


visionastral(Posted 2007) [#12]
Another thing would be making a 3D engine for Blitz MAX based in OpenGL, that would be really great...
(you hear me Mark???)


bytecode77(Posted 2007) [#13]
he's already doing it and everybodys waiting for it(max3d) :P


ZJP(Posted 2007) [#14]
I use the Devil's Shadows system. Very easy. Good job. Sorry French people. Bat english?

JP


_33(Posted 2007) [#15]
I would like to have an estimate on the speed of SSwift's Shadow system. I'm planning to have performance options for high powered systems (Core 2 Duo + Geforce 8800, etc). In essence I'd like to know the speed with big models, like 50K triangles etc etc. Also would like to know the limits in model sizes.

Is there a SSwift Shadow system demo that really taxes a gaming system that I can find somewhere? Not the Bethoven one, but something a little more demanding for powerful systems?


puki(Posted 2007) [#16]
Mmm, it used to be here:
http://www.seamlesstexturegenerator.com/systems/Swift-Shadow-System-Demo-025.zip


sswift(Posted 2007) [#17]
I put it back there. It probably dissapeared back in March when I switched to a new web host. I wish people would tell me these things sooner! :-)

All the demos of my systems were missing. But they're all there now.


_33(Posted 2007) [#18]
Not the bethoven demo, another one.


sswift(Posted 2007) [#19]
Well, here's an old one I haven't made available for a while:

http://www.seamlesstexturegenerator.com/systems/fpstest.zip

The reason I don't generally make it available is because it doesn't provide a much more realistic view of how the system will perform in real case scenarios than the other demo.

Plus, because it allows you to fire 20 moving light sources into the scene at once with four non-animating objects casting shadows, it will either give you unrealistic expectations if your objects are animated and your levels are unoptimized, or make it seem like a framerate hog, because lots of moving lights are expensive and the system isn't designed for that.

Now you might be wondering why I don't just fix those isssues and put out a better demo.

Good question.

The reason for that is because no demo can cover all possible game styles, and it takes a lot of time and money to make demos. The system only sells one copy every couple months and people aren't willing to pay much for it, so it's not worth the time and effort to do so.


_33(Posted 2007) [#20]
sswift,

I tried to find a "bullet point" featurelist of your shadowing system, but to no avail. All I know is that it's a shadowing system that:
- Can cast more than one shadow per object
- Has the possibility of more than one light (duh!)
- Is not stencil based
- Has performance related adjustments (which I find great)
(?)

Your link doesn't work for me.


sswift(Posted 2007) [#21]
What link doesn't work for you, and in what way doesn't it work?

The info link in my sig links to a worklog which contains the following information:


The Swift Shadow System is a Blitz library designed for casting realtime shadows from animated and static meshes onto arbitrary geometry.

NOTE, MD2 meshes are not at this time supported.

B3D bone animated meshes and 3DS segmented animated meshes are both supported.

In plain english, my shadow system can cast multiple shadows from your animated characters onto your level. It can also cast shadows from static objects placed in your level to add detail, such as a desk.


Here is a demo of the system in action, with a number of options to play with:
Swift Shadow System Demo


How it works:
-------------
The system provides three diffrent types of shadows for maximum efficiency. The first two types are dynamic shadows. dynamic shadows change every frame, warping to fit the local level geometry as your object moves around. Of these two, there are rendered shadows, and textured shadows.

Rendered shadows are the most processing-intensive types of shadows. A rendered shadow is created by making a texture that approximates the shape of the object that is casting the shadow, and then applying it to the level surface.

Textured shadows on the other hand are cheats. Textured shadows take a premade texture you specify and project it onto the level. You can use textured shadows to cast round shadows from your characters that deform around geometry. Textured shadows are therefor a lot faster than rendered shadows.

The last shadow type is static. And thus they are called static shadows. Static shadows once rendered are never updated, though can be deleted and recreated on an as-needed basis. Static shadow use rendered shadow maps just like rendered shadows, and so are realistic looking. However, once rendered a static shadow never changes. It is always rendered with the same shadow map, and always to the same polygons, unless you delete it. This makes static shadows very fast, and appropriate to use throughout your world to make level decorations like desks, trees, and buildings cast shadows. The cost of a static shadow is merely the cost of an additional entity, a few extra polygons, and a texture.

In addition to supporting diffrent types of shadows to speed rendering, my shadow system also has several important optimizations. The most basic of which is the light radius.

When you want to create a shadow with my shadow system you specify every obejct that you want to cast shadows, every object that you wan tto recieve shadows, and every object that you want to be a shadow casting light.

For each of these light sources, you can specify a max radius of effect. Any object outside this radius will not cast a shadow for that specific light. This allows you to fill you level with lights and automatically cast shadows from only those nearest the player.

The second more advanced optimization the system does is that is re-renders shadow maps for dynamic rendered shadows only when the angle between the caster, receiver, and light source has chnaged enough that the shadow map has become too inaccurate a representation of the ideal real shadow. This cuts the amount of times the shadow map needs to be re-rendered greatly, and if neither the caster, light source, or receiver are moving at a particular moment then the shadows will render much more quickly than if any of the three are moving at a high rate of speed.

Below you will find a demo of the system, with a number of options you can play with. Take a look at it, and note that the demo has a high number of casters and receivers... More than you are likely to have in one room at one time in many types of game. So the demo is something of a stress test.


Known issues:
-------------
Note that if you double the number of recivers, the number of casters, or the number of lights, then you double the amount of work which needs to be done on a particular scene. That is why you will notice a drop in framerate when you have two lights flying around. Not only are the lights moving quickly, requirng the shadow maps to be re-rendered almost every frame, but you double the work when you add the second one! In many games, you're much more likely to have several NON-MOVING light sources in a room, and characters which move relatively slowly. So this demo is not neccessarily an accurate picture of what the speed will be like in your particular game.

Also note that the shadow system will work better if your level is broken up into several sections made with individual entities. This is how you should construct your levels anyhow for optimal rendering with modern 3D cards. Doing this allows the system to cull whole groups of polygons with simple boundign sphere tests.

Another thing to be aware of is that this system can only cast shadows ont static meshes. The meshes can rotate and move around, and you can even move the vertices around menaully. But you cannot cast a shadow onto a vertex/bone animated MD2 or B3D. You also cannot cast shadows onto terrains because they too animate their vertices internally to the Blitz 3D engine in such a way that you cannot access their changing locations.

You CAN of course cast shadows from B3D and 3DS animated meshes.

One last issue to be aware of is that with a frame tweening based setup, and a light source which is close to the objects being shadowed, the motion of the shadows over the surfaces may not be completely smooth. If you move the light source farther away, or use a delta time based system, then this will not be an issue.

So check out the demo, and the source code that accompanies it. The source code demonstrates how simple the calls are to activate the shadow system, and gives you a good idea of how well commented and formatted the shadow system source itself is.



To purchase this system, go here:
www.blitzbasic.com/logs/userlog.php?user=963&log=267




_33(Posted 2007) [#22]
This link:
www.seamlesstexturegenerator.com/systems/fpstest.zip

But today it seems to work.

Basically what you're saying is you don't have an official SSwift systems website of sorts. Because if you did have that, then I'd follow the links to the various sswift systems and read on from there. I tought a worklog wasn't what I was looking for but more like images of the system working and visual detail of what's doing what. But it seems to have nice performance enhanced tweaks, which is something I am looking for.

Anyhow, thanks for your patience with me.

Cheers.


IPete2(Posted 2007) [#23]
Just Luke,

Having completed quite a few projects using Swifts Shadow system I can advise you that it is without doubt, reliable and simple to use. There is a little bit of setup but it is so easy and tweaking can all be done in realtime too so it is very efficient to work with.

The very best advice with it is to divide your level up into smaller meshes so that it is not working too hard.

Later this year I will post some screenies from my commercial game project on my web site. Its doing me a load of great work currently.

IPete2.


sswift(Posted 2007) [#24]
_33:

Yes, there is no official website.

The worklog did have images of the systems in action at one time, but those broke a long time ago when the worklogs here got destroyed, and I never bothered fixing them.


_33(Posted 2007) [#25]
IPete2, thanks for the thumbs up!

sswift, my present objectives are to have a functionning shadow system for the "marble madness" inspired game I have set up so far.

I'm looking for making shadows of this sort:



That image is using Devil's Shadow System. I've tried to accomplish this using ANDERYman's Ashadow, to no avail. It kept bugging on me past 12K tris model. This model, which is a test, has around 25K-30K tris. It is an absolute fact that I will need the shadow system to do these types of shadows using these types of models, but in multitudes. I won't be using 10 lights, but more like 1 general light, and one player oriented light. There might be at times a 3rd light, but it won't cast far. That's the general idea that I have. I came to the conclusion that a stencil shadow is too demanding for my needs, but is not discarted for smaller tasks that requires very detailed shadowing.

Anyhow, that's what I'm after.

Cheers.


sswift(Posted 2007) [#26]
That's funny, becayse my shadow system was specifically designed for this sort of game. Well the first incarnation anyway. I was developing a game just like that, and I needed shadows cast straight down, so I wrote a system that could do that. Later I added the ability to have the light come from any angle and any location, and optimized it for games which didn't have small polygons set up in a grid-like setup.

BUT, it was designed for casting the shadow of the marble on the terrain. NOT for casting shadows from the level onto the level itself! (Or even from the level onto the marble.)

No object in my shadow system can cast shadows onto itself, and the object being shadowed must generally not be inside the bounding box of the object casting the shadow. (Ie, the level's bounding box encloses the marble. That's a no-no. But the marble's bounding box does not enclose the level. That's good.) The way it works is by rendering the object as black from the light's point of view and then projecting that texture onto the mesh that should receive the shadow. Or rather, a copy of a few clipped polygons in that mesh. This setup does not allow an object to cast shadows onto itself, and objects casting shadows onto objects inside their own bounding boxes won't look right with this setup either.


Personally though, for a game like that, I think any sort of realtime shadows for the terrain itself is a bit of an overkill. In my games which used block shapes very much like that, I just lit the level with flat shading and had a few different floor textures... full bright, full shaodw, shadow one one diagonal half... which I placed around the blocks to give it an "isometric shadows cast at a 45 degree angle" look. The lighting made the appropriate side of the blocks dark, and the shadow textures made the appropriate parts of the ground dark. Of course this setup requires that the whole ground be a grid, and that you don't just ose big polygons for those flat areas. But if you really wanted to stick with that you could always build the shadows into the level geometry itself by making them different polygons, or place shadow polygons that overlay those areas. Or you could use lightmaps, which is kinda what my cheating method was, in a way.

Anyway, if you want realtime shadows cast from the level onto the level and cast from the level onto the marble, then my shadow system is definitely not for you. My system is for both static and animated objects casting shadows onto levels.

You could kind of split your level up there to get a sort of similar look, cause my system will handle stuff like buildings casting shadows onto levels, but I wouldn't reccomend it in your case. That's what I'm doing with the pillars in my Beethoven demo though.

What you're doing is really the job of stencil shadows, or zbuffer shadows, or lightmaps... if you're willing to have static shadows on your level. (And there's no zbuffer shadow systems for Blitz.)


_33(Posted 2007) [#27]
So then I guess I'm back to square one! But I have a better idea of what use your shadow system has.

Thanks.


IPete2(Posted 2007) [#28]
_33,

Swifts system has the ability to set up a lot of static shadows as well as animated b3d mesh shadows and simple soft edge circle shadows. He has a demo called 'city' I think, which shows this off very well. Once the static shadows are calculated, they do not need and further calculation, as long as the light doesnt change.

You must be aware though that for fast dynamic shadows, dividing the game level up into small sections and using a 'switching on the fly' funciton will be the best way forward.

I have a funciton which keeps tabs on where my main character is and where he has just been. This way I always have two sections of my level active for shadows, but the rest is dormant and so no claculations are done in those dormant areas. Of course the moment the main character sets foot a dormant area, it becomes awake and shadows are received as normal.

Turning receivers on and off on the fly is fast and easy to acheive with Shawn's library.

IPete2.


_33(Posted 2007) [#29]
IPete2, if you find other downloadable demos of Swift's Shadow System, I'll check them out religiously and make sure I get the sense of funcionality of this engine. The city demo sounds quite appealing. I have plans for building cities in my game, so obviously I would like to put in all the nice shadowing. Yet building do cast shadows on other buildings. Just wondering how that would look like with this engine. So if I understand, this system doesn't allow a shadow to cast to the sending caster? So Bethoven's bust isn't self shadowed by the swift shadow system in demo 025?

Cheers.


sswift(Posted 2007) [#30]
There is no self shadowing in my system.

I didn't realise the city demo wasn't included with the demo download. The system itself includes the city demo. I've updated the demo zip to include the city demo, so if you download it again, you'll get that:

www.seamlesstexturegenerator.com/systems/Swift-Shadow-System-Demo-025.zip

As you can see, you can cast shadows from buildings onto the ground, and onto other buildings. A shadow map is rendered for each building and then used for the ground underneath it and the surrounding buildings. If the shadows overlap then you get darker areas.

Each building here is a seperate shadow casting object. If you combined all the buildings into a single shadow casting object, then the shadow map would probably be too low res. With this setup however, you can have one of the buildings be destroyed, and at that time delete the static shadow it casts, or change the shadow from static, to dynamic, and then animate its destruction with proper shadows.

Static shadows are shadows where the shadow map is rendered once, and then never again, and the shadow polygons are generated once and never again. They're fairly efficient, the cost being one entity and texture per shadow.


_33(Posted 2007) [#31]
Hmmm, indeed, this looks like proper shadowing of both ground and buildings. Neat, and seems quite fast! The featureset seems very good Sswift! It's probably sad that there ain't a website that rightfully gives justice to your system. I'll consider spending the little it costs and try to exploit this technology in my project.

Thanks again SSwift for all that patience and good will.


Dock(Posted 2007) [#32]
Why don't you use lightmaps, such as gile[s]?


Vertigo(Posted 2007) [#33]
_33 honestly how in the heck do you have 20k-30k poly's on that map? it requires such low detail that I mean.. man haha. Why do you need them realtime? Just use a light mapper, and you can shade the marbles when they are in shadowed zones or something.. save yourself some cpu.


_33(Posted 2007) [#34]
Dock, some day, not now. My experience with gile[s] has been negative up to now, since I have not yet properly exported my blitz generated models.

\/Ert|g0, it is software generated, and not optimized. If you have a mesh optimizer, then talk to me about that. Hahaha...

Thanks for the ideas guys, but I'm trying to have as much realtime generated stuff as possible. Having everything pre-rendered is not my goal.


Dock(Posted 2007) [#35]
If your level is created within Blitz, then perhaps you could use one of the lightmappers that are written in Blitz. Isn't there once called 'YAL' that you might be able to implement?

Other than that, I'm stuck for ideas. Devil's system sounds likes it ought to be fine for you, but without optimising more it could be too much of an overhead. I suspect you might be asking too much control from Blitz3D in this regards though.


_33(Posted 2007) [#36]
Dock, I do plan to optimize my meshes. I've studied a way to do so, and it shouldn't take me 2 years to write (!). I'm not the fastest coder around, so whatever I try to do, I think a long time before doing to make sure it's properly done. And doing a mesh optimization routine with multiple surfaces to me sounds like a couple months work. But this is part of my mid/long term goals.

Now the problem with DSS is not the shadows in themselves, it's more that I will have to use that + AShadow's water + post process etc etc... And that will be a tough one because I will have to blend the two to make a new type of system. I've already changed the code of AShadow so I can actually read what RenderStates he's doing and for what reason, as he doesn't comment at all.

Example:
BBSetRenderState(52,1)
BBSetRenderState(57, 1 )
BBSetRenderState(58,$ffffffff)
BBSetRenderState(59,$ffffffff)
BBSetRenderState(55, 3)
BBSetRenderState(54, 1) 
BBSetRenderState(53, 1)
BBSetRenderState(56, 8)

my version:
BBSetRenderState(D3DRS_STENCILENABLE,1)
BBSetRenderState(D3DRS_STENCILREF, 1 )
BBSetRenderState(D3DRS_STENCILMASK,$ffffffff)
BBSetRenderState(D3DRS_STENCILWRITEMASK,$ffffffff)
BBSetRenderState(D3DRS_STENCILPASS, 3)
BBSetRenderState(D3DRS_STENCILZFAIL, 1) 
BBSetRenderState(D3DRS_STENCILFAIL, 1)
BBSetRenderState(D3DRS_STENCILFUNC, 8)



Vertigo(Posted 2007) [#37]
Noting that it also looks like youre using 16 bit color mode judging by the dithering in those screen shots. Ive noticed some funky issues with the ashadow lib if you dont use 32 bit. Here is what I would do. Make a lot of small meshes and tile them. Each piece has an angle etc. Each one has a corresponding 45° shadow plane on it. just fake it with the shadows. Honestly you are using a lot of complex graphics work for a game that is really simple looking. Marble madness was an amazing game.. but its was game play that made it... tough game play at that.. it was addictive and fun. Forget about the glimmer and sparkles for a moment. Go grab an nes emulator(or console if you still have one haha) and play the game for a while... think simple. Im a pathetic programmer when it comes down to it, and I know it wouldnt take me more than an afternoon to have a crude level editor working for that system. Ditch the graphics lib. Make some fake shadows and make the game fun... Honestly I cant wait to play this, so hurry up about it too haha.


_33(Posted 2007) [#38]
\/Ert|g0: I'll do it just for you, promise.


MeowZ(Posted 2007) [#39]
Hi,

Can I use Swift Shadow System with B3D SDK? (C/C++).
I am not sure Swift need to access Systemproperty(Direct3DX7) or not, because B3D SDK does not have this function. T___T.

waiting for answer,