Vector maths in lighting tutorial

BlitzMax Forums/BlitzMax Programming/Vector maths in lighting tutorial

spacerat(Posted 2009) [#1]
A friend and I have created a lighting engine using a guide, and we have the drawing side of it all completed, along with working shadows for rectangles. However, I am trying to follow http://www.gamedev.net/reference/programming/features/2dsoftshadow/page3.asp this to get the lighting engine to work for any convex polygon, but it's not working.

Firstly, I'm not sure exactly what they mean by dot product. I've seen dot product defined as dot = (a.x * b.x + a.y * b.y), - which seems to be more prevalent in vector libraries - and I've seen it defined as dot = |a|*|b|*Cos(theta) - which is what most mathematics sites define it as - so I don't know which to use.

Secondly, you need "the vector to the light". Is this from the point you're looking at, or from the centre of the polygon?

Here is my code cut down to the problem area. For some reason, this is sometimes classifying the edges as back or front facing incorrectly.
Local prevpoint:Vec2 = Vec2(Points.Last())
For local point:Vec2 = EachIn Points
	'Calculate normal of polygon edge
	Local nx:Float = point.y - prevpoint.y
	Local ny:Float = point.x - prevpoint.x
	Local normal:Vec2 = New Vec2.Init(nx, ny)

	'Get vector to light
	Local observer:Vec2 = New Vec2.Init(observerx - PrevPoint.x, observery - PrevPoint.y)
	
	'Calculate dot product
	Local frontfacing:Int = normal.DotProduct2(observer) > 0
Next


Observer is a vector for light position. DotProduct2 is the dot product with Cos(theta) in it. The other dot product (a.x*b.x+a.y*b.y) doesn't work either.

Can anyone point me in the right direction here? If you want me to post more code, or a working example, then please do ask.


Floyd(Posted 2009) [#2]
Although far from obvious the two definitions are equivalent.

Length*Length*Cos(angle) is what the dot product really means.

x1*x2 + y1*y2 ( + z1*z2 etc. for higher dimensions ) is the practical way to compute it.

Lengths are never negative so the dot product has the same sign as Cos(angle). This is positive for angles less the 90 and negative for greater than 90. A dot product of zero means the vectors are perpendicular.


spacerat(Posted 2009) [#3]
Interesting, I didn't know that. So I'll use x1 * x2 + y1 * y2 for dot product. Unfortunately it still doesn't work. If the dot product of the normal of the edge and the vector the to light is positive, the edge should be detected as facing the light, but it seems to be almost random at the moment.


spacerat(Posted 2009) [#4]
Well, I solved it, by accident through trial and error really. For a start, it seems "normal" in that article was an error, because the code I've got, and in fact the code he supplies, is certainly not a normal. I think it's the perpendicular vector in mine. Here's the code:
For local point:Vec2 = EachIn Points
	'Calculate "normal" (or not) of polygon edge		
	Local edge:Vec2 = Point.Copy()
	edge.SubtractVec(prevpoint)
	Local normal:Vec2 = New Vec2.Init(- edge.y, edge.x)
	
	'Get vector to light
	Local observer:Vec2 = New Vec2.Init(observerx - Point.x, observery - Point.y)

	'Calculate dot product
	Local frontfacing:Int = observer.DotProduct(normal) < 0
Next



Warpy(Posted 2009) [#5]
A normal is a perpendicular vector.

Edit: just realised where you were confused. A "normalised" vector is any vector that has been scaled down to have length 1, but a "normal" vector is one that is perpendicular to some other vector you're interested in.
It's confusing, which is why I prefer to call vectors of length 1 "unit vectors".


slenkar(Posted 2009) [#6]
got any screenshots?


GW(Posted 2009) [#7]
Someone already made a mod for this type of 2d shadow. It was way back near the time when Bmax was first released so the code is probably GL based. That might help you understand the algorithms.


spacerat(Posted 2009) [#8]
Thanks for the info Warpy. I've got a feeling that would have continued to confuse me for a long time if you'd not have told me that.

And yea, here's a screenshot



My friend did most of the technical work on the actual lighting. On top of making it work with any convex polygons (you can only see rectangles in the screenshot though) I persuaded him to untie the code from the rest of the game so that it can be used in other projects. Perhaps when it gets mature enough, and if my friend is ok with it, we'll release it on here along with the geometry module on which it relies. However, I think he wants to add soft-edges first, like in the second half of that tutorial.