A really easy way to do real-time shadows that is applicable for actual game use

Blitz3D Forums/Blitz3D Programming/A really easy way to do real-time shadows that is applicable for actual game use

JoshK(Posted 2003) [#1]
This is ridiculously simple.

Okay, we all know you can render an object from the point of view of the light and transform camera coords into UV coords, and do some real-time lighting, but there were always problems actually applying it to game use. Edges went beyond the camera size and other bad stuff happened.

If you poke around in Unreal }{ you'll notice that shadows are just transparent objects that are raised slightly from the surface they are on. Multitexturing doesn't produce the z-fighting that I have seen shadows give on occasion in the engine.

Step 1.

Identify what object you want to cast a shadow for and what light source you are using.

Step 2.

Render the object from the light source. Transform Vertex positions to screen coordinates to make sure your viewport is big enough to accomodate the whole object.

Step 3.

For every surface that is facing the camera, and the camera faces, transform it to camera space coordinates. Do not transform screen coordinates. Correct for Z position relative to the camera by calculating a slope from the area filled by the shadowed object. If the corrected vertex position lies outside the area given by the most-outlying vertices in the object we are shadowing, it is not shadowed.

Step 4.

Knowing which surfaces receive shadows and which do not, copy the surfaces and texture these new, transparent surfaces with the render output. Assign UV coordinates based on x and y position, where x and y are relative to the extreme values for their given z position relative to the camera.

The key difference here is you should assign UV coordinates by transforming the vertex position to camera space and correcting with tformedz(), rather than using screen coordinates. Your code would probably multiply the transformed x and y coordinates by tformedz() and some constant, derived from the area and closeness of the shadowed object.


Alternatively, you can do even faster shadows by simply using a pre-rendered shadow texture, like the fans and other map objects in Unreal }{ have.




JoshK(Posted 2003) [#2]
Hell, let's test this. BRB.


sswift(Posted 2003) [#3]
Simple in concept. Easy to program? No. Easy to make fast? Hell no!

This is really similar to the method I use in my shadow system.

That method is, (ignoring special optimiztions)

1. Calculate normal from light to shadow casting object.
2. Use normal to create 5 plane shadow frustrum from light to shadow casting object. (Plane 5 being at the sahdow casting object' center, seperating it from the light source.)
3. For each shadow receiver, determine if it is in the shadow frustrum with quick sphere test.
4. For any shadow receivers in the shadow frustrum determine which polygons are inside the shadow frustrum. Test does not have to be 100% precise, just has to be fast and make sure ALL polygons IN frustrum are found.
5. Project planaer mapped light-space texture coordinates onto polygons in the shadow frustrum.
6. Apply shadow texture.


To render the shadow texture:
1. Create copy of entity off in some far corner of the world.
2. Find the widest axis of entity.
3. Scale entity down by widest axis length so it is guaranteed to fit in a box of size 1.
4. Point camera at entity from light source location relative to the entity in the real world.
5. Render shadow map.


I mentioned a few simple optimizations but there's a lot more than that that I put into my system.


I don't quite have a grasp on exaclty what you're describing but you gloss right over assigning UV coordinates to the surfaces. Also I'm not sure how this method could take advantage of inter-frame coherency.


JoshK(Posted 2003) [#4]
It'll have to wait until I start exporting from CShop3. This is way easier to do when you are using brush geometry.

Think of a square-based pyramid with the apex at your light source, that is just wide enough to contain your object that is casting the shadow. You CAN calculate the change in height and width as a function of distance from the apex, pretty easily. For any distance from the camera, just consider a cross-section of the pyramid, and the edges represent UV values of 0 and 1. Then transform your 3D coordinate to 2D coordinates in that cross-section of space and assign UV coordinates based on its position relative to the 3D edges we designated as representing the extremes of the shadow area or UV area, 0 and 1.

What it will do:

Very fast pre-rendered (but moving) shadow maps on any CShop level, like a shadow of a rotating fan, being cast on a lot of surfaces at once.

Pretty fast dynamic shadows on level surfaces, like player shadows.

What it won't do:

Whole rooms cannot be dynamically lit. Only certain objects will cast shadows.

Although shadows can be cast on a polygonal model, it will be a bit slower, and should be used with care.

Objects cannot cast shadows on themselves.


This isn't hype or BS. This will definitely work. I'll put the source out once I have a good example.


sswift(Posted 2003) [#5]
I'm not saying it's hype or bs. Just that you're underestimating the difficuly and speed. :-)

The slowest thing about shadow projection map algorithms is rendering the shadow maps. The second slowest is either culling the polygons or building the mesh.

Hm... I wonder if there's a potential way to speed up the polygon culling bit.

I wonder if it would be faster to precalcualte some information about the receivers to speed culling and use a diffrent culling method.

The way I cull things right now, I use a view frustrum and test each polygon in the receiver against each view frustrum plane in turn. If any fail, the test exits early. If all pass the polygon is close enough to being inside the view frustrum that it's included. Only a few stray polygons will occasionally pass when they should not, which has little to no effect on the rendering speed.

But what if I created a 3D array for each object that is receiving shadows, and for each cube of the array I placed indexes to all polygons which intersect that cube.

Then I could find the cubes which are in the view frustrum, and that would contain all the polyogns in the view frustrum, and a few extras outside it. I'd have to transform the view frustrum into object space though or else the cubes would be at odd angles.

But what if I forgo the cubes and use overlapping spheres instead?

Hm... interesting... I just sketched out a pattern to create the least number of circles you need to cover an areas completely in 2D and the result is a pattern of hexeagons and pentagons which emrges... Just like the surface of a soccer ball.

I wonder if you can get a similar result in 3D.


JoshK(Posted 2003) [#6]
Ah...you are doing it on a triangle basis, which i said would take a lot longer. I am counting on brush geometry to go a lot faster, since every surface is coplanar, and there are a few tricks you can do.

I'll let you know what I find. I am much more willing to do open-source community projects now, since it's a lot faster than each person figuring out there own version of everything.


sswift(Posted 2003) [#7]
"I assume you know what I mean by a pyramid with the apex at the light and the sides touching the outermost edges of the casting object."

Yes halo. That is a view frustrum. I don't use a phyramid though. I use lights which are a hybrid of point, spot, and dfirectional lights. So my shadow frustrums are rectangular. This greatly cuts down on the number of faces which can potentially be in shadow.

"You CAN tell if a vertex lies within that pyramid."

Well aware of that Halo. Like I said, I find out which triangles are within my shadow frustrum.

And you can't simply discard triangles based on a single vertex being out of the frustrum Halo. You also cannot assume that any triangle that is in the frustrum will have a vertex inside the frustrum. There are all sorts of cases where a triangle can cross the frustrum and have no points inside it. The algorithm I use takes those into account at the expense of letting the occasionaly couple extra polygons outside the frustrum be included by mistake.

"If it is still slow, just assume that this will be fixed when you implement better vis routines, so less walls need to be tested."

I just tell people to split their world up into multiple entities. You should not have a level be one huge solid entity anyhow. If they split the level up into an entity for each space, then my algorithm will cull all the spaces outside the shadw view frustrum with just a sphere test for each one.

As I said, the slowest bit is the shadow rendering. You can lose 10fps or more on that alone. So that is what I focused on speeding up.


"It would also speed things up a lot if you knew that every surface is coplanar, as is the case with brush grometry."

Not by much, if at all. You could test a few less verticies maybe.

In my system half the polygons on the world are culled with the first plane test. That means all three vertices of each polygon in the world are tested against a plane.

Half of the remaining polygons are then tested against the next plane. And half of those against the next. And so on.

So it's very optimized. Here's the first set of nested if statements for testing a tri against a single plane.

								; Is polygon below top plane?
								If (A1#*VX0# + B1#*VY0# + C1#*VZ0# + D1#) > 0
									Poly_In_Region = True
								Else
									If (A1#*VX1# + B1#*VY1# + C1#*VZ1# + D1#) > 0
										Poly_In_Region = True
									Else
										If (A1#*VX2# + B1#*VY2# + C1#*VZ2# + D1#) > 0
											Poly_In_Region = True
										EndIf
									EndIf
								EndIf




As you can see, if the polygon is in the region at any point, it exits early. And if the polygon is completely on the outisde of the plane, then it also exits early and doesn't check it against any of the other planes.


Doing something special for coplanar polygons would probably just slow it down.


"You can also just use a shadow texture to speed things up dramatically, if your object is just going to spin like a fan."

Yes, my system supports fake shadows. Those are much faster than rendered shadows. And yes, a clever person could simply call rotatetexture to make the fake texture rotate all the time. In fact, my system supports static shadows as well. Shadows which render a mesh, and then never update that mesh. So if your fan is being lit by an unmoving light source, then you could just use the fast static shadows which would be as fast as applying a static lightmap to the level. Except that you could rotate the texture to make the shadow turn.


But making a shadow map for a rotating fan isn't easy. I mean what would the shadow map look like? It would only be applied to a small section of the room... you wouldn't want the whole room covered. So would you just have the fan blades themsevles cast a shadow? I suppose that could work if the rest of the room was light with lightmaps and the lightmaps did not have the fan blades baked into them, only the light coming through the hole itself.


JoshK(Posted 2003) [#8]
Sorry if I am saying obvious things like they are really hard for you to understand. I try to say things really explicitly, because everyone has their own lingo, and it's hard to talk about these things clearly.


sswift(Posted 2003) [#9]
Hm... You know, maybe I should reorder my plane checks. I'm thinking that it's far less likely for vertices to be above or below the top and bottom planes of the light view frustrums, and much more likely for them to be to the left or right of the sides of the view frustrums, because worlds generally are oriented horizontally.

Still, I'm sure it wouldn't improve the speed much. It's rendering those darn shadow maps which is is the major slowdown.

If I knew more people were actually using my shadow system in their games and what sorts of situations they were using them in then that would help and encourage me to optimize it more.

But so far nobody's said to me that they have any problem with the speed, except for special cases where they do crazy stuff like make every tree on a golf course cast a shadow. :-)

I think it might be possible to optimize the shadow map rendering a little more than it currently is, but I'm not sure.

What I do to opmimize that is minimize the numebr of times I need to render a new map. I do this by calculating how much the angle between the caster and light source have changed, even taking into account rotation of the caster. Unfortunately I can't optimize for animated meshes in this way.

I could possibly create a more optimal routine so it has to update the shadow map even less often, but it's hard. I think that I could cancel out the entire roll part of the equation by rotating the texture now that I think of it. That would just leave changes in pitch and yaw as causing the system to need to render a new shadow map. I think though that for most cases that would not really have much effect on the number of times the map needs to be updated.

Perhaps another solution would be blending shadow maps. To do that I would need to forward predict where I think the entity will be in the future, and then blend the two shadow maps together to smooth the motion and hide snapping from one orientation to another. But I don't see how to blend the maps with alpha without doubling the number of polygons that need to be created for the shadow mesh. The number of polygons in the shadow meshes are a source of a big speed hit too. So it's not a good idea to cast shadows onto highly detailed meshes such that a lot of the poygons in the mesh are in shadow at the same time.

I suppose it might be possible too to reduce the number of polygons which need to be created each frame for the shadows. Perhaps it would be better to simply add polygons for two frames and only clear the whole thing every other frame instead. The extra polygons would not cause any problems.

The thing is this is still an imperfect solution, and it would jsut make the whole system even MORE complicated and difficult to modify than it is already. It was so nice when all I did was a 2D clipping operation and I transformed everyhting into light space with a call to rotatemesh.


podperson(Posted 2003) [#10]
The best realtime shadows I've seen are in NeverWinter Nights (e.g. the players cast shadows onto scenery, scenery casts shadows onto scenery, players cast multiple shadows from multiple lights etc.) Are they using your technique Swift?


sswift(Posted 2003) [#11]
I don't know. I have not played the game.


Zmatrix(Posted 2003) [#12]
best Shadows ive seen where in the doom3 beta
every object casts a proper shadow (including self shadowing)
Course the beta wasnt that fast. averaged about 29 fps on my athlon Xp 1600/radeon 8500 128meg
but thats not to bad for an unoptimized game thats looks that good.


Zmatrix


sswift(Posted 2003) [#13]
Doom 3 uses stencil shadows, which unfortunately, even with "Carmack's Reverse", an optimization Carmack came up with which dramatically increases their speed over previous methods, are only really useful in low polygon worlds, because for each shadow volume you have to fill that area of the stencil buffer twice. Which means areas where multiple shadows overlap require tons of fill rate. If you imagine geometry as simple even as a jail cell, the overlapping shadow volumes cast by the bars of the cell would kill the framerate. With worls getting ever higher levels of detail I don't see stencil buffer shadows as being the future of shadows except in games with simpler graphics.

Take note of how the monsters in Doom 3 are all low polygon with bump maps to add the appearance of additional detail. This is because of those stencil shadows.

Hopefully some new technology will come along which solves these problems. I thought zbuffer shadows would solve the problem but I hear that they have issues with lights which are behind the camera. I don't know what those issues are though, so maybe they are solveable.


sswift(Posted 2003) [#14]
Hmm.. interesting. I just added a little profiling code in my shadow system, and you know those nested IFs which check each triangle against the shadow frustrum?

Well, after doing my test I determined that in that one-light scene in my demo, there's between 1200-3000 triangles tested each frame. And on average there are 5-7 multiplies done per triangle in the plane tests.

Another test displayed the scene with no shadows at all, and it ran about 140fps. But if fake shadows were added, fake shadows being simply, projected textures, no texture rendering, the fps dropped to 90. As I turned wait for refresh off, these are true fps changes, not the result of a small change causing a wait for refresh.

Now framerate drops have to be taken with a grain of salt. At high framerates, even a small drop in speed can result ina large drop in framerate because the number of milliseconds between each frame is small.

So you divide 1000 milliseconds by both values, and then subtract one from the other. And that tells me that approximately 3 milliseconds are being spent in the code which does the projection and culling. Which is the amount of time which one frame would take to draw at 333fps. Sounds better that way, doesn't it? :-)

But that's not fast enough for me. It shouldn't be taking three milliseconds. It should be taking ONE!

I think I might have a solution though. If the average triangle is requiring 5-6 muls per frame, before being culled, then surely I can speed that up. Right now I'm testing using a shadow frustrum comprised of several planes. I wonder though, if I could trivially reject most polygons with a simpler check, like a sphere to line check, before they even get to this function.

I'll have to see if I can find a mathematically simple way to generate a containing sphere for a tri.


JoshK(Posted 2003) [#15]
I assume you are using a combination of the distance between the sphere center and a plane defined by the triangle, and the distance between the triangle verts and the center of the sphere?


JoshK(Posted 2003) [#16]
haha...I feel kind of bad for shutting down your server. I didn't think they'd do that, I just thought they'd email you or erase the offending files.


JoshK(Posted 2003) [#17]
hmmm...lI took another look at your demo. You realize your shadow resolution is like way higher than the highest setting in Unreal II? I get a constant 60 FPS with two lights.


Dock(Posted 2003) [#18]
The shadow resolution in sswift's demos is merely that - a demonstration. Chances are you wouldn't use it that high, but if the game structure required it then it's just an option :)

It seems that Neverwinter Nights is using the exact same technique as SSwift's shadow system. There's no shadow casting on to anything but the static scenary. There are some good screenshots here: http://www.jivemagazine.com/content_gamereviews.php?ID=21


sswift(Posted 2003) [#19]
"You realize your shadow resolution is like way higher than the highest setting in Unreal II?"

No, I had no idea, I have not played Unreal II. The shadow res can be lowered to 128x128 in the demo, it defaults to 256x256. Are you saying the shadows in Unreal II are lower than 128x128?


"I assume you are using a combination of the distance between the sphere center and a plane defined by the triangle, and the distance between the triangle verts and the center of the sphere?"

Right now, I am using a shadow frustrum made from planes and determining if all of the triangle's vertices are on the outside of any one of the planes.

That is taking 5-6 muls on average per triangle. Sometimes as many as 7.



"I assume you are using a combination of the distance between the sphere center and a plane defined by the triangle, and the distance between the triangle verts and the center of the sphere?"

And I have no clue what you are saying. Are you talking about some way of storing the triangle sphere?

Because what I inteded to do was find a sphere that encompassed the points of the triangle, not neccessarily a very close fit sphere, but close enough, and then determine that sphere's squared distance from a shadow ray, and if that distance was greater than a squared radius of the shadow ray then the triangle would definitely be outside the shaodw view frustrum.

However, I am finding that calculating the sphere that contains the points alone would take like nine muls, three divides, and some IFs.

To find the sphere that encompasses the points, first I must average the points to find the center of the triangle. That requires a divide for each axis.

Then I have to find the squared distance of each of the points to the centerpoint I just calculated.

To do that I have to use three muls for each vertex.

And then I have to choose the distance which is the greatest, which will require between 1 or 2 if statements.

Once that is done I'd have the coordinates and radius of my sphere.

Now, I COULD precalculate all that. I'd rather not get into precalculating stuff though, more than I already have.

Anyhow, then I would find the closest point on my ray to that sphere.

Unfortunately, this is the straw that breaks the camel's back.

To find the distance of a point to a line requires six muls and a divide. Which is more expensive than the current system.

Hm. And I thought I was onto something there for a minute.

Still, I refuse to accept that I need to do 6 muls per triangle just to trivially discard them.

I could perhaps pre-sort the triangles into some kind of bsp tree or put them into a cube array but that would be cheating. And besides I don't know enough about BSP trees to figure that one out easily right now. And I don't want to have to store all the vertex info for a mesh in the shadow system.

I'll find a way.


Beaker(Posted 2003) [#20]
sswift - you really should look at doing a coarse sphere test and then a less coarse sphere-to-cone test before (or even instead of) doing any frustrum-plane tests.

Hope that makes sense.


sswift(Posted 2003) [#21]
I just looked at those shots of Neverwinter Nights, and I think what they are doing may be similar to what I am doing, but may also not be quite the same.

If you look at the shots the shadows are very sharp looking, and the dragon's shadows seem to overlap without darkening eachother, which is correct behavior. My shadow system would not behave that way. Of course other shots appear to have the overlapping shadow thing going on, but those are where more than one light is visible.

It may be that they are generating a shadow map for each light that covers the whole area. Given that their shadow engine only has to work for top down view games, they could put in optimizatons which I cannot.


sswift(Posted 2003) [#22]
"you really should look at doing a coarse sphere test and then a less coarse sphere-to-cone test before (or even instead of) doing any frustrum-plane tests."

That's just what I was discussing. I already test entire entities with a sphere test, but to test individiual triangles that way, as I just described, would actually be quite a bit MORE expensive than just skipping to the plane test, as un-intuitive as that may seem.


JoshK(Posted 2003) [#23]
What I meant about the resolution and Unreal II is you may be holding your system to standards that are much higher than even the AAA games, and perhaps you should aim at a system with lower-res shadows, but have more of them, and try to manage them on a bigger map.

Can't you store shadowed surfaces so that shadows only get moved when the light or the casting object are moved, so for something like a rotating fan, you would only need to calculate which surfaces the shadow hit once?


sswift(Posted 2003) [#24]
"Can't you store shadowed surfaces so that shadows only get moved when the light or the casting object are moved, so for something like a rotating fan, you would only need to calculate which surfaces the shadow hit once?"

I could, but what would be the point? The vast majority of objects a player will want to cast shadows from will either be moving around the world, or not move at all. Both these cases are covered. A special case like a rotating fan isn't something many people will do, and as I stated previously one can use a static shadow to model that and rotate the texture manually.

I can only think of one case where a player would have a lot of objects that need to cast dynamic shadows but do not move much of the time, and that would be an RTS. And if you're makign an RTS you're not gonna want to use complex shadows like this. And even if you did, all you'd have to do is manually generate a static shdow for a tank when it stops moving and delete the dynamic one, and vice versa when it gets moving again. This assumes you're SANE of course, and only have one light source casting shadows in your RTS. :-)


Beaker(Posted 2003) [#25]
sswift - can you think of a neat way of getting shadows to fade out the further they are from the casting object (using your existing system)?

I had VertexAlpha in mind of course.


sswift(Posted 2003) [#26]
"can you think of a neat way of getting shadows to fade out the further they are from the casting object (using your existing system)?"

Of course. I could do that. Nobody ever asked for it though, so I never bothered to implement it.

You wouldn't want to fade the farther it was from the casting object, you would want it to fade the farther it was from the light source.

I can do that per vertex even. So a long shadow would fade out if it stretched a long way from the light source. Or I could do it per shadow which would be a little bit faster, but not much.

It should be really simple to add.


Beaker(Posted 2003) [#27]
Although the distance from the light source is useful and more natural. I would want to do it the distance from the casting object as well.

Games aren't always about realism. In my game I could probably manage with one 'directional' lightsource (the sun). This may even simplify the number of tforms you need in your shadow code, maybe?

Catch me on IRC chat (UK/US time) if you want to talk it through.


sswift(Posted 2003) [#28]
Ah. I can see why you might want it to fall off based on distance from the caster. This would simulate how shadows blur the further they are from the object casting the shadow.

I'll see if I can't implement some global value for that as well as the light falloff.


sswift(Posted 2003) [#29]
Got basic light falloff in, but I still need to tweak it cause it's falling off too rapildy.


(tu) sinu(Posted 2003) [#30]
"It seems that Neverwinter Nights is using the exact same technique as SSwift's shadow system. There's no shadow casting on to anything but the static scenary. There are some good screenshots here"

actually they do cast shadows onto pc players.
I once did a cel-shaded character for and shadows cast upon it and they looked pretty cool.
Also it's not a top down view game, you can have the camera anywhere around the player.


Mustang(Posted 2003) [#31]
Sswift,

I will start soon once again messing around with your shadowsystem... but first few questions since we are talking about your shadowsystem here...

I don't have my game code here (I'm at work) but I think that you could set the shadowmap size for every object - which is good. But it would be much better IMO if you could set the RESOLUTION (texel/m [1 blitz unit]) for the shadows instead; I have cases like where "shuttle", "player" and "cargobox" are next to each other in the level and the result is that bigger object have very jagged (shadowmap) edges compared to the smaller objects.

I could of course use bigger maps (and do) for bigger objects but the mapsize (128, 256, 512 etc) rarely corresponds the dimensions/scale of the models... so they are not looking very good in some cases. I know that you try to ooze every pixel out of the space the shadowmap has, but I would like to have an option to use "consistent texels/meter" shadowmap resolution - I know that it would lead to cases where you have to create map with lots of wasted space on it but the result would be neater?

Also one additional question: would it speed things up if the system could use "shadow objects" ie low-res meshes instead of the "real" ones when it's doing the shadowmap?


Dock(Posted 2003) [#32]
Sinu - any chance of a demo of your shadow casting on to the player method? I was under the impression that SSwift's system couldn't cast on to animated meshes.


Mustang(Posted 2003) [#33]
SSwift's system couldn't cast on to animated meshes.


IMO no Blitz-made system can - because you can't get the vertex info. To my knowledge this is why you can't have animated (deforming/boned) meshes as a receiver. Of course rigid (hierarchial) animated meshes work with Sswifts system too.


sswift(Posted 2003) [#34]
Mustang:
You don't HAVE to use power of 2 sizes for the shadow textures, you can use any size you want, so long as they're square. So you can use 192x192 if that suits you. I can't guarantee that your video card won't scale the texture to a larger size though and/or potentially create artifacts.

Dock:
I don't beleive it is possible to cast shadows onto animated meshes. He mentions cel shading, which leads me to beleive he might have tried using some kind of spherical map to do it, but I don't think that would work that well.

Besides, how often do you need to cast shadows onto a character? To cast shadows onto a character you'd need to cast shadows from your level, and for speed, that's a no-no, except for objects within the level like crates or barrels or trees.


Mustang(Posted 2003) [#35]
Mustang:
You don't HAVE to use power of 2 sizes for the shadow textures, you can use any size you want, so long as they're square. So you can use 192x192 if that suits you. I can't guarantee that your video card won't scale the texture to a larger size though and/or potentially create artifacts.



Ah. The thought of using non power of 2 textures never even occured to me - too used to using power of 2 textures always or something? :)

...But i think that it (using non power of 2 values) might prodice artifacts or Blitz3D will scale them or something. Have to test that.


Beaker(Posted 2003) [#36]
Yep. You are better off changing the EntityColor or, if you have lots of spare processing, the vertex colors, to cast 'shadows' onto animated meshes.


sswift(Posted 2003) [#37]
Yes, it's possible you will get artifacts on some video cards with non power of 2 textures. But most modern video cards, the ones which can handle the kinds of scenes you'd be using for shadows in anyhow, can do non power of 2 textures. Anyhow the artifacts aren't really gonna be noticeable with the textures moving around so fast.

But I still don't see why 256x256 and 128x128 and 64x64 aren't adequate enough. I don't think anyone's gonna notice that the textures are of slightly diffrent resolutions on objects which are somewhere between those sizes.


"Yep. You are better off changing the EntityColor or, if you have lots of spare processing, the vertex colors, to cast 'shadows' onto animated meshes."

I can see changing the entity color to make an entity darker when it passes into a dark area, but you can't get the changing locations of vertices in an animated mesh, so accessing them in pointless. Of course, as some have pointed out, if you use boned meshes you can transform the vertices by the bone, but that would be so incredibly slow it wouldn't be worth it.


Ps:
I got the falloff working pretty well now, but I'm getting strange results in that the falloff I specify has to be like 2-4x that of Blitz's to match the light sources in my test scene, so I'm gonna have to wait till Mark gets back to me on my questions about what the lighting equations in Blitz are before I am happy with the implementation.


Mustang(Posted 2003) [#38]
I don't think anyone's gonna notice that the textures are of slightly diffrent resolutions on objects which are somewhere between those sizes.


I'll notice them :) (I'm a perfectionist...) well, I'll get back to you if it (difference in resolutions) becomes untolerable.


Beaker(Posted 2003) [#39]
sswift - for my game I would probably prefer the falloff to end at the 'height' of the shadow.


sswift(Posted 2003) [#40]
"sswift - for my game I would probably prefer the falloff to end at the 'height' of the shadow."

Afraid I can't/won't do that. :-)

To do that I would have to calculate the vertex which is closest to the light source and the vetex with is the farhtest from the light source and that would slow things down and be a pain in the ass and only you want to do that. :-)

Also what of special cases like a shadow which only angles away from the object a little, or not at all? Can't fade that case like that. It would look totally wrong.

But what I am going to do is make it so that you can set the distance from the caster at which the shadow fades out completely. That should be adequate.


Dock(Posted 2003) [#41]
how about creating a falloff start, and a falloff finish... so that for example, you could have a light with 5 metres full shadow, and then 3 metres where it fades from full to zero shadow. This ought to be flexible enough to allow shadows from the sun with decent fallout.


sswift(Posted 2003) [#42]
"This ought to be flexible enough to allow shadows from the sun with decent fallout."

Since I am allowing you to set both the falloff of the light, and a secondary falloff to simulate how shadows blur and fade out the farther they are from the object casting the shadow, having a good falloff with the sun casting shadows is possible. You just set the falloff for the sun to be very far, and the falloff for the character to be within a meter or so, and voila.


podperson(Posted 2003) [#43]
NWN's been hacked to support First Person -- far as I know, shadows work fine.

BTW: I looked at your demo at last (I do most of my downloading using my Mac and your site doesn't work for my browser)... it kicks ass. Very very nice. I don't think the NWN folks do colored translucent objects... I will definitely look at using it once the actual game play part of my current project works.

Again, very nice work.


(tu) sinu(Posted 2003) [#44]
i wasn't on about blitz i was on about shadows being cast on characters in nwn. They use only heirachy animations though.Sorry for the confusion.


sswift(Posted 2003) [#45]
I now have basic shadow falloff working in my shadow system. Unfortunately, Blitz lights have a HUGE falloff! Like, if you have a light with a radius of 20, the falloff goes out to 5100 units!

I think.

According to the equations Mark gave me, that's what happens.

So I implemented a little bit of a hack, where you can select the maximum brightness level for the shadow to fall off to. So you can specify 8, and it won't get any lighter than 256-8, where 256 is the point it fades out completely. So it'll just dissapear at that range.

But that's not really good enough for me. I'm not happy with the shadows just dissapearing, and even with a radius of 8, the shadows still go way the hell out there.

So maybe I need to implement a secondary max radius you can specify which somehow makes this thing fade faster. I'm not sure yet.

The fades look nice as they are, but you just can't have shadows being drawn over 80 meters from a light source. It would not be good for the framerate.


fredborg(Posted 2003) [#46]
Stupid question:
I assume you are using a camera to render the shadows? Isn't it possible to simply use fogging to make the fade?

Fredborg


sswift(Posted 2003) [#47]
I am using a camera to render the shadow maps. But these maps are rendered from a fixed distance from the object at a fixed scale. So no, I can't simply use fogging to make them fade.


Beaker(Posted 2003) [#48]
Also, you would need to be able to fog in the Y axis instead of the Z axis. :P

When do we get a sexy demo sswift?


podperson(Posted 2003) [#49]
MasterBreaker:
Doesn't fog happen in the camera's Z axis? I don't see a problem there.

sinu:
I'd say NWN is using skeletal animations implemented using IK. If that's only hierarchical then only hierarchical covers pretty much everything most of us care about, no?


sswift(Posted 2003) [#50]
"When do we get a sexy demo sswift?"

When someone sends me a sexy model. Beethoven just doesn't do it for me.


"Doesn't fog happen in the camera's Z axis? I don't see a problem there."

The character sticks up from the ground. So even if you rendered a view from the light source with the character black and the background white, fog would still not produce an appropriate image. The top of the character would be NEARER to the camera, rather than farther away like it would need to be if it represented the shadow on the ground which is flat and pointed away from the camera.


fredborg(Posted 2003) [#51]
Ahh, I thought you just wanted, objects further away from the light to cast a less intensive shadow...

Fredborg


Beaker(Posted 2003) [#52]
sswift - you need a nice animated b3d character model. What about using one of Psionics lovely creations?


sswift(Posted 2003) [#53]
I don't really feel like modifying the demo to add an animated character. :-) Besdies... It's got a beethoven theme to it!


Space_guy(Posted 2003) [#54]
Well you should atleast consider updating it with some more lights or something. I cant get the framrate to lower below 85 on one of my computers no matter what settings i chose in it. hehe
Perhaps throwing in a light or 2 more could really get the computer a workout :)


sswift(Posted 2003) [#55]
"I cant get the framrate to lower below 85 on one of my computers no matter what settings i chose in it."

Geez! What you got a 4ghz machine? It drops to 35 on my system with 2 lights.

On the other hand another guy who recently tested it on a 1ghz with geforce 3 said he only got like 9fps with one light!

And I know that a Geforce 3 is way better than my Radeon 7200, and I was getting like 30fps with two lights when I had my Celeron 433!

So that guy's PC is just weird. :-)

Anyhow with two lights casting shadows, you're basically rendering 14 diffrent shadow maps at once... double the number of shadow casting objects in the scene. So that's why it would slow down.

Ooooh!

I just realized something!

Aren't there some new geforce drivers which positively SUCK at rendering text on the screen? I bet THAT'S why his framerate was so terrible!

In fact a lot of text hurts my own card too somewhat. I should put in a way to hide all the text and/or only display an fps counter.


I'll think about making it so you can press 6 to cause your computer to burst into flames with 4 lights. :-)


Space_guy(Posted 2003) [#56]
pls do that :) id like to see what your system can do :)
so far it looks great!


Anthony Flack(Posted 2003) [#57]
I get a solid 75, even with 2 lights, so long as I stick to 128x128 textures. Thats with a p4 1.4 with Geforce 2 pro.

There is a game idea I have planned for the future which I will definitely want to purchase the shadow system for; it looks great, runs sweet and is definitely out of my league coding wise...


Space_guy(Posted 2003) [#58]
oh my. after the latest nvidia driver update all my computers max at there refresh rate at maximum settings.
:)


Anthony Flack(Posted 2003) [#59]
But aren't you the guy who owns 3 really powerful top-of-the-line computers, all with screamingly fast next-gen 3d cards in 'em?


Space_guy(Posted 2003) [#60]
eeerhmm hehe


Beaker(Posted 2003) [#61]
sswift - you really are missing an opportunity to show what your system can do if you don't have an animated thing going on, MD2 or B3D.

You chicken or something? ;)


Anthony Flack(Posted 2003) [#62]
Quick - whip up a spastically dancing beethoven figure!


Zenith(Posted 2003) [#63]
If anything, do a bitmap-based FPS :D
[then you won't have any text commands]