Shadows For a Large Environment

Blitz3D Forums/Blitz3D Programming/Shadows For a Large Environment

ClayPigeon(Posted 2010) [#1]
Hello. I'm working on a FPS in which many of the levels consist of an entire island with plants and all. I'm having to do a lot of optimization (fading plants, dynamic LOD with terrain, etc.) to prevent slowdown. What I want to know is what shadow technique would work best for such a large environment? Obviously, stencil/volume shadows are out of the question. All the detail I require is enough to get rid of the "flatness" of the scene. Shadows that are far from the camera don't have to be detailed, just enough to see a hill cast a shadow on the ground. I do, though, want to have small objects up close have a low detail shadow as well, but there just needs to be enough detail that the player can SEE there's a shadow there. I was thinking the best method would be shadow mapping, as it only requires you to create a camera at the light sources. But, from what I've read, people here seem to be convinced it's impossible. Anyone got any ideas??


Robert Cummings(Posted 2010) [#2]
Vert shading sounds like an easy bet.


ClayPigeon(Posted 2010) [#3]
Shadows, not shading. If you mean to make shadows using vertex colors, that would be too CPU costly, having to go through each of the vertices and do a linepick to find out if there was a straight line between the camera and the vertex.


Kryzon(Posted 2010) [#4]
NEVER underestimate the power of vertex coloring. It is being used by professional game developers up to this day.
It provides you with a shading capability at no cost of performance and memory (since every vertex already have those attributes to start with).

I want you to look carefully at the following screen grabs from Super Mario Sunshine for the GameCube.

Full scene as in the game:


WITHOUT vertex color:


ONLY vertex color:


Pretty much all the shading is done through vertex colors. There are some baked textures like the ones for the roofs of the huts and for the trees (that aren't seen in these screens, but you can see one baked tree shadow at the middle, leftmost side of the screens).


ClayPigeon(Posted 2010) [#5]
You are right - I agree. Except that appears to be made for static shadows, and it actually looks like they modelled the shadows into the level. I've played SMS and the sun never changes angle. Also, if you look at Mario's shadow and compare it to those seen on the walls, you will see that Mario's shadow is all pixelated, whereas the shadows on the wall are perfectely smooth. From this, I'm guessing they are using shadow mapping for dynamic shadows, and static for.. static. Also, if I remember correctly, when Mario runs into a static shadow, his shadow is still visible, even though it is completely obscured by a wall.


Kryzon(Posted 2010) [#6]
Indeed, they did model the shadows in the level (if I turn on wireframe I can see the edges for the shadows, even though these extra polygons don't interfere with the original topology).

As it is for lots of games out there: static lightmaps\vertex-shadows for environment and static objects; dynamic shadows for dynamic objects.

Not only the problems you pointed out, but also the fact that since all these shadows are coming from the same light source (the sun), they should all meld together to the same tone. However, when mario steps under a tree's shadow or these shadowed zones from levels, his shadow gets even darker as it's being blended into the ground. This doesn't happen in real-life.
However, we are dealing with a simulation here. It's very easy to point out irregularities since it will be always far from reality.

Let's realize that the experts at Nintendo were aware of these problems and still let them go by because the "juice wasn't worth the squeeze".
With all these things you and I pointed out, Super Mario Sunshine still has a metascore of 92%, from MetaCritic.


Ross C(Posted 2010) [#7]
I agree you shouldn't get too bogged down on the technical details like that. It's going to be near impossible to have this kind of lighting, in blitz3d, real time.


ClayPigeon(Posted 2010) [#8]
I realize what you're saying, but without shadows, everything just is terrible. I need something to show lighting. Is there some super-lowres method that gives big blurry shadows or something? I'm actually not sure how slow linepicks are, so I might try that.


puki(Posted 2010) [#9]
but without shadows, everything just is terrible

Yeh, this has proven to be a problem for me. I use FastExtension and LOD it like a mother.





http://www.youtube.com/watch?v=B99AGwi-VFE


The point being this is all near-range.

Without it - the whole thing sucks when you have seen it with shadows.

Your CPU is potentially going to hold you back. I'm going to have to upgrade my CPU to deliver more oomph to Blitz3D.

I use real-time shortcuts by using EntityColor, 127, 127, 127, etc to apply fake shadow cover to entire meshes. So, if I have a rock in shade behind a house, I just EntityColor the equivalant shade to it, I don't need to apply the shadow, unless it is partly shadowed - this method is handy for things which are sheltered by buildings, etc. You can real-time alter this on the fly and also use it convincingly for animated meshes, such as characters - so you cast a shadow from the building to the ground mesh then, use EntityColor to apply fake shading to anything that falls within this area. It is certainly faster than trying to blanket a whole area of vedgetation, etc with a real-time shadow.

I wouldn't worry too much about the distant objects, like hills, etc as it is just not practical.

FastExtension is not really designed for this; however, I find it works a treat for indoor FPS-type environments.


Kryzon(Posted 2010) [#10]
I realize what you're saying, but without shadows, everything just is terrible. I need something to show lighting. Is there some super-lowres method that gives big blurry shadows or something? I'm actually not sure how slow linepicks are, so I might try that.

Oh, sure, I didn't mean "don't use shadows at all". Lightmaps and shadowmaps are really the way to go (and you could also use vertex-coloring to spice things up a notch, if the sun isn't moving).
What I wanted to say was something like "don't dwell in the attempt of perfection, since you won't get it anyway. Stick with the acceptable".
Oh, and I'd advise against linepicking\raycasting, as nobody uses that because it's too slow to do it real-time.

I don't know how FastExtension works for shadow-maps. I do know that of all the [few] shadow-map solutions available, it's definitely one of, if not the best (both visually and performatically speaking).
You could try to use lower resolution shadow maps for distant objects (similar to a method known as "Parallel-split shadow-maps") and blur that a bit (or not at all). Pay special attention to the bias of the shadow, if it spreads too far from the object in an unrealistic manner.

If you're in doubt of where to begin, start with the Lightmap(s) of your level. Use something like Gile[s] (freeware) to do it, and set up the quality you want (it has a good packer and can split your level into several lightmap textures to ensure a very good quality).
After that, get your hands dirty with dynamic shadows for objects, even if they don't go beyond simple faded sprites at ground level (what matters is the final result, after all).


ClayPigeon(Posted 2010) [#11]
Lightmapping? I've been down that dark, cruel road. In the beginning, it seems "so nice" and "perfect for everything"! That is, until you try to move the sun, and *POOF!* you hate it permanently.

Your CPU is potentially going to hold you back. I'm going to have to upgrade my CPU to deliver more oomph to Blitz3D.


Sounds familiar. I have a Celeron D. Talk about SLOWWWWW!!

I'm gonna see if I can make some kind of primitive shadow map system real quick.


Kryzon(Posted 2010) [#12]
Hmm, I'm not sure I agree with you in that; lightmaps have been used for "decades". At the cost of a static sun, of course.
Does a day~night cycle play an important role in your game? there might be other ways to simulate that.

But then, can you tell me what game before Crysis had the feature of environmental dynamic shadows for a moving sun? so, any game that came before Crysis that had a day~night cycle system probably used some other method.


ClayPigeon(Posted 2010) [#13]
can you tell me what game before Crysis had the feature of environmental dynamic shadows for a moving sun?


Well, there's one I can think of right off the top of my head: Uru. But, it doesn't have a day-night cycle; it just stays how it is when you get there and you can play it for days, but it stays the same. I guess I'll have to do away with the day-night cycle.. Man, I miss the days when blob shadows were enough, 'cause then you could just move the sun anywhere, and the shadows didn't really matter. So, maybe I can keep my day and night cycle and just make the shadows always be casted straight down?


Kryzon(Posted 2010) [#14]
That could work.
You'd have the environment's and sky's color change between day and night tints, to give the illusion of time passing. That should be more than enough to give the feeling, as well as changing the ambient sound.


ClayPigeon(Posted 2010) [#15]
Sounds good. I've got a simple top-down shadow system going. Now, I just can't figure out how to get the orthographic camera to have the edges of its view exactly at the edges of the terrain? Something about the zoom level?


Kryzon(Posted 2010) [#16]
Hmm, there must be some ugly math to do that. It's related to getting the bounding rectangle for the top-view of the terrain, and getting the best fit of that with the current camera FOV angle (which makes a pyramid).

EDIT: Actually, scratch that. Use trigonometry (which I think would only work for a 90 degree FOV camera):

To get the top-view bounding rectangle of the terrain, get the extremity vertices at the Z and X axis (no Y, since this axis is removed in an orthogonal top-view). You need to find out the Height of the triangles formed by the Z or X axis in relation to the camera's FOV slopes (they form a triangle, like the one seen in the image). Finding the height of this triangle is the same as finding the best-fit-height that the camera has to be. If your terrain is not square-sized, then one of them will have a bigger height, and that is the one you should use (if your terrain IS square-size, I presume they will both result in the same height).

You could spend some time trying to find that out, but I'd go the easy route and in 3DS Max position a camera with the FOV of 90 Degrees (this corresponds to a zoom of 1.0 in Blitz3D) until I've got the best fit on the viewport. Then I'd write down the height of the camera and use that in Blitz3D (or export the scene as a .B3D and set a Dummy in place of the camera, so that is read as a Pivot inside Blitz3D).


ClayPigeon(Posted 2010) [#17]
Man, I miss 3DS Max! I used to have it, but then I migrated to a newer computer with XP and Maxis didn't make the drivers for the hardware lock thingies for XP. (that's because I used Max 3!! XD) Also, the exporting and dummy = pivot stuff would be really useful to make realtime cutscenes for games which is another thing I've been trying to figure out.

And, about the alignment of the camera, sorry, but I'm still a little confused. Why would there be a triangle for orthogonal projection? The only thing that changes when you move the camera on the Y axis is the position of the clipping planes..?


Kryzon(Posted 2010) [#18]
It's all abstraction, it's just a way to look at the problem.

The camera has an angle for it's Field of View. We can imagine the frustrum based on this angle:

If you can write down the equation for the problem above, in post #16, then you could set the Height of this triangle as the unknown value, and find it out.

Well, since you mentioned Orthogonal, I guess the height of the camera needs to be the same as the size of the bigger side of the top-view bounding-rectangle of the terrain.
Find the bounding-rectangle, get the biggest side of it, center your camera on the terrain, and lift it up until that height. Then point it down.


ClayPigeon(Posted 2010) [#19]
Whoops! It appears I have gone all my life thinking orthogonal was just another way of saying orthographic.. Well since I have the camera set to ortho, nothing happens when I move the cam up. It's going to have to be done purely through CameraZoom. The terrain is 512x512, and the camera is 512 above the terrain, and the closest to the perfect CameraZoom I've gotten is 0.01.


Rroff(Posted 2010) [#20]
If you have a 512x512 unit terrain and a 512x512 pixel camera then you can set the zoom to 1.0/256 to frame it perfectly in an ortho camera mode.


ClayPigeon(Posted 2010) [#21]
Doublewhoops!!! I just realized all my problems were due to thinking my terrain was 512x512. It's actually 256x256 and 1.0/128 is working perfect - thanks.
Here's what I've got:

It's VERY simple, but it can be modified to be better. What I can't figure out is the coloring thing. To get the shadows to all be black, the only way I could get the entities to be black was to set the ambient light to 0,0,0 and hide the shadow-receiving objects and make the camera's cls color 255,255,255. Is there a better way of doing this??

EDIT: Also, when an object is lower than the ground it still casts a shadow. I think I could somehow change the terrain during the shadow render instead of hiding it so that it could obscure the objects that intersect with it.

ALSO EDIT: I think it would be more efficient to have a small section of terrain that conforms to the ground as it follows the cameraor something and is transparent, because then I could have the shadow camera follow me above and render a higher quality shadow map for the close objects then do some kind of lower-quality render that doesn't happen every frame for further away objects.

LAST EDIT (I'M SERIOUS): Basically, what would make my life easier would be how to change a mesh to a solid color TEMPORARILY regardless of the texture on it and be able to return it to its previous state. With this, I could turn all the casting objects white, and the shadow map texture would be a lot easier to render!


jfk EO-11110(Posted 2010) [#22]
I think, day and night cycle or not, you should use something static, prerendered for static objects, everything else is an overkill. How about to render 12 Lightmaps, then use a texture crossfading every 10 minutes or so. Because, in realtime you won't notice that the sun is animated, it looks static.

It may be a further challenge to get something like additional, dynamic lights in the scene, like a flashlight or a cars lights.


ClayPigeon(Posted 2010) [#23]
OK, I guess you're right. But, do you know of a way to make a mesh a solid color even if it's textured and be able to change it back to the way it was?


jfk EO-11110(Posted 2010) [#24]
I remember I usually used a white, small texture. Just use GetBrush to store the original brush. Note this will create a new brush that is identic with the one in the loaded mesh, so don't recreate it again and again.


puki(Posted 2010) [#25]
Or just get a chuffingly fast CPU and Large-it real-time - that's the option I am taking. The point being that real-time is just so beautiful - it just really is.


jfk EO-11110(Posted 2010) [#26]
You can't expect everyone to have a hitech cpu and gfx card. And even then there will always be limits, esp. for outdoor scenes. If I had to do everything in realtime and I had the power do do it, I'd rather use a pixelbased Raytracing, sort of "what is the 3d location of this pixel, and what light can see it." But this is one of those things that works better on optimized customr risc chips than on a CPU with bus and everything.

I tried it in plain Blitzcode :) I had a very low resolution with a framerate of 1 fps or so. Maybe someone else can do it better.


Rroff(Posted 2010) [#27]
I tried pure blitz3D based raytracing, just for shadowing, no light interactions, caustics, etc. and even using low accuracy and some "hacks" the best performance was 4-5fps at 640x480 (the actual tracing quality was lower but it could be upsampled to 640x480 before you started to really notice the glitches in the sampling.)


puki(Posted 2010) [#28]
I wonder how well Xors3D shunts shadows in Blitz3D? I've never really used it, it certainly does have a lot more jiggery-pokery than FastExtension.


jfk EO-11110(Posted 2010) [#29]
Rroff that's not bad. You should test that on Pukis machine.


Rroff(Posted 2010) [#30]
Oh I forgot to mention... that was on a fast clocked (4GHz) core 2 duo heh... unfortunatly I messed the code up somewhat trying to tweak it even more or I'd share tho its not that interesting.


ClayPigeon(Posted 2010) [#31]
@jfk: That's what I was thinking the other day, conjure up a 1x1 tex with the desired color and add a layer it.


_PJ_(Posted 2010) [#32]
I recall Spellforce (2003) had some nice environmental and character shadows that woul elongate and fade as the sun moved through the sky and finalyl disappeared when it set. The LOD was quite aggressive, though, so at the (rather short) long-distance, the shadows et al would simply vanish.


That's about all I can contribute, sorry :(


Zmatrix(Posted 2010) [#33]
problem is that core2duo, only getting half its speed, blitz only uses 1 core that i can tell...least on a X2 64 , i don't recall ever checking on my 6800 duo when i had it.
maybe someone else can check, run in a window and bring up task manager and see if it can get above 50% ,

so at 3.1 ghz per core id be better off with a 3.7ghz single core p4 extreme?

now back on topic..lol

its pretty easy to manipulated textures u/v on the terrain
http://www.blitzbasic.com/codearcs/codearcs.php?code=384

maybe you can combine that with the code above and and generate a map around the player position . The edges would need some kind of falloff, probably similar to fables shadows they had a smooth falloff at distance, that was a cube map im guessing.
but this would allow for sharper shadow maps as they wouldnt have to scale over the entire map.
hope that gives you some idea's atleast.


Sam


Yasha(Posted 2010) [#34]
problem is that core2duo, only getting half its speed, blitz only uses 1 core that i can tell


You can use the free FastPointer library to get multithreading in B3D (although be aware that you have to ensure thread-safety yourself).

see if it can get above 50%


A high processor-usage statistic is a bad thing. You should be aiming to keep your usage a low as possible, to keep the CPU nice and cool and let the operating system have some time to itself. Since Blitz3D hogs processor time, it'll actually always stay at 50% or 100% or whatever the maximum available to it on your system is, unless you force it to free time with Delay.


Kryzon(Posted 2010) [#35]
...or WaitTimer().


_PJ_(Posted 2010) [#36]
It's generally a GOOD thing for applications to be ABLE to use all processing power availablewhen required. Hence why multithreading across cores > single threads only using one core.
It pervents slowdowns and bottlenecks if the processor usage is limited and that limit reached.
However, Yasha's point is correct, that the allocation of processor time ought to be freed up a little (I find best with a delay of between 1 and 15 milliseconds during each "loop") for the runing of background processees etc.


Zmatrix(Posted 2010) [#37]
thanks for the clear up Yasha :)



can you tell me what game before Crysis had the feature of environmental dynamic shadows for a moving sun?


oblivion,(2006) but only only some objects , doesnt seem to have a unified lighting system ( you can turn it on in the INI, but it breaks after a few min, like the first few npc's and items you run into will have full shadow mapping casting onto the environment (up to like six seperate dynamic lights), you can put object with holes over the a light and it will cast out correctly ,,,but eventually it just stops working and nothing has shadows

and fable, but now that i think about it...while it had a full day night cycle, and the bumpmaps updated to the sun/moon position, i dont think the shadows moved at all.
maybe someone can clarify.

Sam


Rroff(Posted 2010) [#38]
For outdoor stuff oblivion just had a projected shadow image that often didn't even match the object supposedly projecting the shadow - i.e. all trees had the same leaf/branches pattern shadow even completely different types of tree. Only the inside sections had proper dynamic lighting and as you say it breaks easily.

Farcry had a dynamic shadow system to a certain extent with some advanced options you could enable via the console.

A few racing games prior to Crysis also have dynamic shadows cast by the sun but thats a fairly easy thing to hack up as the player is limited as to where they can go and what angles they can see things from.


Kryzon(Posted 2010) [#39]
'nother thing someone might try is a static implementation of Shadow Volumes, kinda like the ones Devil's Child has made for Blitz3D.
If you could stop the shadow updating and just let them static like that, it shouldn't be much of an overhead to render and would still allow you to slightly move the light-source ocasionally (just to update the shadow's position), or if the system has this feature, to pre-calculate all the positions (the Devils Child's system allows this).


Rroff(Posted 2010) [#40]
Someone wrote a function to create shadow volumes and posted it on here and someone else half implemented the ability to clip them (purely b3d code) - obviously too slow for realtime useage but would be perfect for pre-computed static stencil shadows.


Kryzon(Posted 2010) [#41]
You know, the shadow volume for a whole environment would be very complex and fill-rate demanding.
However, with the appropriate combination of occlusion and PVS techniques, that could be reduced to a very good performance.

The benefit would be to have your environment cast shadows on the characters and dynamic objects at almost no cost.
But special things like trees and picket-fences that use an alpha-blended texture to simulate detail might make things a bit tougher. They would need special, simpler meshes for the volumes, or a shadow-map.


_PJ_(Posted 2010) [#42]
But special things like trees and picket-fences that use an alpha-blended texture to simulate detail might make things a bit tougher. They would need special, simpler meshes for the volumes, or a shadow-map.



In a way, wouldn't this somwhat defeat the "point" of using alpha'd textures rather than meshes with the holes in?
Apart from collision detections I suppose.....