The Shadow Matrix

Once again, into the foray of trying to understand matrices better…

I have created a matrix that creates “shadows” of an object with this code:

function CreateShadowMatrix(groundplane, lightpos)
  local dot
    shadowMat = matrix()  --I overwrite all values so this is fast to declare

  -- Find dot product between light position vector and ground plane normal. 
  dot = groundplane.x* lightpos.x +
    groundplane.y * lightpos.y +
    groundplane.z * lightpos.z +
    groundplane.w * lightpos.w

  shadowMat[1] = dot - lightpos.x * groundplane.x
  shadowMat[5] = 0. - lightpos.x * groundplane.y
  shadowMat[9] = 0.- lightpos.x * groundplane.z
  shadowMat[13] = 0.- lightpos.x * groundplane.w

  shadowMat[2] = 0.- lightpos.y * groundplane.x
  shadowMat[6] = dot - lightpos.y * groundplane.y
  shadowMat[10] = 0.- lightpos.y * groundplane.z
  shadowMat[14] = 0.- lightpos.y * groundplane.w

  shadowMat[3] = 0.- lightpos.z * groundplane.x
  shadowMat[7] = 0.- lightpos.z * groundplane.y
  shadowMat[11] = dot - lightpos.z * groundplane.z
  shadowMat[15] = 0.- lightpos.z * groundplane.w

  shadowMat[4] = 0.- lightpos.w * groundplane.x
  shadowMat[8] = 0.- lightpos.w * groundplane.y
  shadowMat[12] = 0.- lightpos.w * groundplane.z
  shadowMat[16] = dot - lightpos.w * groundplane.w

return shadowMat
end

In draw() I render my array of cubes with this code:


    lightVec.x = lightVec.x +.5  -- declared in setup(), below. Move the list source...
    groundPlane = vec4(0,1,0,0) 
    shadowMatrix=CreateShadowMatrix(groundPlane, lightVec)
--other code here
.
.--- you know, the exploding stuff in the video...
.
---render the cubes
   for k,v in pairs(tm) do
        pushMatrix()
        translate(v.x,0,v.z)
        applyMatrix(shadowMatrix)
        Cubes.mshadow:draw()  -- copy of the Cubes:mw cube with black color, 32 alpha, no textures.
        popMatrix()
        
        pushMatrix()
        translate(v.x,v.y,v.z)
        Cubes.mw:draw()
        if v.y > .5 then v.y = v.y - .25 end  --create falling effect
        popMatrix()
    end

In setup() I have this code:


--unused, but I think I need it for this to work!
    bias = matrix()
    bias[1]=.5 bias[6]=.5 bias[11]=.5 
    bias[4]=.5 bias[8]=.5 bias[12]=.5
    bias[16]=1
    
    lightVec = vec4(0,193,0,1)
    groundPlane = vec4(.20,1,0,0) 
    shadowMatrix=CreateShadowMatrix(groundPlane, lightVec)

However, for some reason I don’t understand, by the time my object “touches the ground”, the shadow sems to be “centered” on the object x and z axes, whilke sitting correctly on the y=0 (ground) plane. Moving the light source and recalc’in the shadow shows this situation; the shadow stays centered on the object instead of being attached to the “proper” place on the object.

Sample video:
http://www.youtube.com/watch?v=pmvE_fCU5fI

Woot! I figured it out! I’ll post code later.

It was that the shadow is rendered when the object is both ABOVE AND BELOW the ground. I have a cube, and the center of the cube is y=0, which means that half my cube is underground. The below ground shadow shows up on the opposite side of the above ground shadow. I’m wondering what I can do on my matrix code to ‘remove’ this problem.

The matrix will always calculate some result, you cant solve this with the matrix. you have to decide in some condition to render the shadow or not. Didnt look exactly what you do, so i’m guessing: You could draw a line between the light, the object and the shadow. the order has to be light - object - shadow. if the object is below the plane, then the order will be light - plane - shadow. you could find out that order and then not render in last case.

I am culling out anything below the line now, so anything with a negative Y is being removed. Sort of…anything with a center of negative Y, which means that some polygons ‘stick out’ of the ground. I think I have to cull based on vertices vs. center of meshes.