A new shadow system

Blitz3D Forums/Blitz3D Programming/A new shadow system

Braincell(Posted 2004) [#1]
I've been thinking about making a completely new shadow system for Blitz which will be the fastest and most usable at the same time ever. I had a few ideas but after being force to modify the code several times I discovered limitations. Now I'd like to discuss some of my ideas which I think are valid, and if anyone points me in a good direction I will do all the work to finish the system so that the whole community can benefit.

We all know about sswifts shadow system (which has nothing wrong about it), but I want to try and make a faster one, and for some more importantly, a free one.

Here is the main idea that I was/am working on (please read the whole thing):

*Edit: This is just the first idea, which I conclude here isn't so efficient. The second idea listed below is more probable to be a success.

Each mesh reciever is firstly processed to make a higher poly "map" of it. So a 100*100 plane is divided into say 1*1 squares, each with 2 polygons. The size of each square can be set depending on your needs. Each poly is processed then, and the coordinates of each of the virtual vertices are saved in a file. This is applied to all triangles on any mesh that can be any shape or size, as long as they dont use bones or other similar deformations. Now why do we make this? Once we have this file on disk for each mesh, and each mesh entity has a name so that they can be related, we do the following. There is a light in the scene, can be more. We first make a bounding box around the caster. Then we project 6 lines into infinity each starting at the light and going down onto each corner of the bounding box. This makes a 6-sided pyramid. We go through each mesh that is close enough to the camera and see if each of its polygons is inside the 6sided pyramid. So far only maths are used, no other major blitz-specific function. Once we see that at least the part of the tri (polygon) is inside the pyramid, that means that part of it is shaded. Then, we access the saved high-res mesh version of the mesh which is recieving the shadow. We find the big tri in it, and where each of the small triangles is located on it. Then, we go through each of the triangles vertices XYZ and do a LinePick cast from the vertice towards the light. If it hits the caster first, that means that in this small area (which is predefined in the saved file) there is a shadow, and a small transparent black tri is formed (using a certain 3 vertices stored in that file) to darken the main mesh right there. Then it goes onto the next small tri on and on through the current big tri (on the mesh) and looks if they are in shade. Once done, it moves onto the next tri on the mesh, and so on. It also checks if the triangle on the mesh is inside the camera view, the "4 sided pyramid". So this is what the DrawShadows() function would look like:


	wipe the previous shadows
	
	1-for every caster in the level (including receivers which cast)
		2-for each light that influences the caster
			3-for each mesh whoose shadows need to be calculated (in camera range)
				4-for each poly that needs to be shaded (is inside light and camera pyramid)
					5-shade those polys from the high-res map file
				next
			next
		next
	next



Now theres a lot of smaller finetuning I've done. The function that makes the small triangles on big triangles makes it so that you cannot see the differences around the edges of each triangle on the mesh since the edges are closed together. This is all maths, some of which I have already done.

But you see the problem don't you? In my tests on an average P4, 256 MB RAM, with GForce 4 440MX, I could get no considerable slowdown until the drawn shadow triangles reached more than 2500 and LinePick reached more than 7000. On my better P4 at home, that number was 4000 and 10000, but the ratio there can change. This means that the shadow polycount can be max 2500 and that a max of 7000 small tris can be checked before there was slowdown. I should have expected this. But. As for the small-tri count, that can be reduced by smarter checking of the big triangle. That is what I'm working on now, and this could possibly decrease the number of LinePicks needed as well. But honestly I don't see a great solution coming with this kind of system. However, with this kind of thing we could make the shadows have a gradient by assigning a uvw coordinate to a newly made vertex.

I could probably decrease the polycount of the shadows by making more inteligent code, but i'm looking towards finding better ideas replacing linepick. I dont believe collisions would be faster.

There are a few other ideas, and together with the stuff already written I'd like to hear your thoughts about them. Some of you surely have more experience than a n00b like me! So here is one i think great idea i just had:
Each STATIC mesh has its VertexXYZ accessible using the Blitz commands. Sadly, not so for boned ones. I could make a mathematical function to check angles between certain vertexes and the light, so that the ones that are furthest out create the outline of the mesh. But the mesh can be hollow. Then, that outline could be projected using a part of the system previously mentioned down onto the recievers. We would have a much smaller polygon count, and LinePick would be eliminated, but there will be one problem. We would previously have to make an extra file containing information about which vertice (connected to each poly on the mesh) forms an edge with which other vertice(s). Only then could this be used, with of course a truckload of maths!

So far that is the only next idea i'm keen to discuss but I have others too.

Also, I've finished mathematical functions checking if an edge (a line) is inside a 4-sided pyramid in space. This could be useful for anything else at least, if nothing comes out of it.

sswift, please don't be "un-constructive" to us and to yourself! ;)


N(Posted 2004) [#2]
First off, I hope you're good with math.

finding better ideas replacing linepick


Coldet. Look for elias_t's wrapper in the Toolbox.

Now, after reading most of that, I really don't know what advantages this would present over sswift's or any other shadow casting system. Frankly, this sounds like it'd be much slower thanks to the increased polygon count through subdividing triangles into a great deal more triangles. The best way I can see of doing shadows is projecting a shadow texture (created by a render to texture procedure) onto the receiving mesh (such a system would not require you to calculate the position and alignment of bones or vertices in a mesh [typically] for animated meshes). (Easier said than done, I know)

Anyhow, just me rambling, and I've already forgotten where I was going with my response.


Braincell(Posted 2004) [#3]
Oh ye, I think I'm good enough with maths.

Coldet. I'll look into it. Thanks.

You didnt read the "great idea" at the end. I was saying, same like you, that that would be slow, so I should have probably devoted more space to the other idea that i want to work on now. I just talked about the first idea in case anyone could notice any obvious improvements. Also I think it will be faster than swifts. A shadow of a 2000 poly mesh would be made of about 300 polys, since only outlines are calculated and the rest is filled in, but cut off at the edges of any reciever poly. So maybe more polys in some cases, but linepick will be gone...

Oh and isnt the way of doing shadows you mentioned, basically sswifts one?


N(Posted 2004) [#4]
I don't own sswift's system, so asking me if it is sswift's technique is pointless.


Jeremy Alessi(Posted 2004) [#5]
Yeah Sswift's renders a texture. I can't remember if it's cast directly on the polygons or if a proxy mesh is made and laid over the area ... but I think it's cast directly. At least in the old version which we used in AA. Aerial Antics had one problem though. Logic was updated at 60 FPS. I used to have this thing with game control being updated a lot and always went overboard ... but that would slow things down quite a bit. Anyway, Sswift's system is plenty fast ... you just have to use low polygon proxy recievers and such. Aerial Antics used all low polygon collision detection and shadow recievers.

Personally, I think it's a bit late in the game to develop a new shadow system. B3D is already old and on the way out sometime next year once BMax has it's 3D module. If you plan on releasing a game between now and then ... just use Sswift's system and save yourself a few weeks work. If you're not actually making a game and just doing it for the intellectual stimulation ... have fun and good luck.


sswift(Posted 2004) [#6]
"I've been thinking about making a completely new shadow system for Blitz which will be the fastest and most usable at the same time ever."

Hehe. Good luck! But I won't go down without a fight! :-)


John Pickford(Posted 2004) [#7]
You lost me at the 6 lines bit; doesn't a bounding box have 8 corners?


Braincell(Posted 2004) [#8]
Jeremy:
Yes, intellectual stimulation is what i think this is. Also what you say about B3D is true, but i think still it'll take a while b4 BMax picks up that much pace. So i think it'll take about a 1.5 years from now till when its fully 3d usable. Just my opinion!

sswift:
Youre on buddy!!!!!!! :))))

John:
It has 8 corners but viewed from a point other than front,back,top (where it has 4), etc, it projects as a 6-sided shape!!


Zeotrope(Posted 2008) [#9]
So did the new great shadow sys ever see the light of day?

I see a shadow monopoly being that of sswift

:)


Stevie G(Posted 2008) [#10]
It did, it was a stencil system, it was bugged to hell and unfinished so completely unusable.


Dicon(Posted 2008) [#11]
Sswift.
I finaly got your shadow system working. My fault. A way out of date Blitz re-installed after a crash but NOT UPDATED.
( blush )
Looking good, and using it with .3DS exports and Giles.
Thanks.
Dicon


Zeotrope(Posted 2008) [#12]
I thought so!

The monopoly lives on.