In my first pass, I move the GL camera to the same position as the light. I render the scene to a texture and it uses a shader to save the depth from the camera (aka light). Here is core code for the depth saving shader

vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;

float depth = (length(viewPos)-near_clip)/(far_clip-near_clip);

gl_FrontColor.r = depth;

gl_Position = ftransform();

I view this texture in a pwindow and it looks like I would expect it to look. I think this step in the process is ok.

Also on this 1st pass, I use a JS sketch to save the matrix needed to later index into the texture w/ depth data. Here’s core code:

sketch.glloadidentity();

//texture scale-bias matrix

sketch.gltranslate(0.5, 0.5, 0.5);

sketch.glscale(0.5, 0.5, 0.5);

sketch.gluperspective(light_lens_angle, 1.0, light_near_clip, light_far_clip);

sketch.glulookat(light_pos[0], light_pos[1], light_pos[2],

light_lookat[0], light_lookat[1], light_lookat[2],

up[0], up[1], up[2]);

matrix = sketch.glget("modelview_matrix");

On my 2nd pass, I move the camera to my desired location. I then render the scene using a phong shader with added shadow mapping. This shader works correctly with the phong shading. Its when I add my buggy shadowmapping code that it fails. I bind the texture w/ the depth data on to the OB3D objects. I also pass the matrix calculated above in JS (called lightToTex) into this 2nd shader. In the vertex shader, this is the shadow specific code:

varying vec4 shadowtexCoord0;

varying float dist;

uniform mat4 lightToTex;

curPos = gl_ModelViewMatrix * gl_Vertex;

dist = length(gl_LightSource[0].position.xyz - curPos.xyz);

shadowtexCoord0 = lightToTex * gl_Vertex;

In the fragment shader the shadow specific code is:

varying vec4 shadowtexCoord0; // Used for shadow lookup

varying float dist;

uniform sampler2D tex0;

float shadowdepth = texture2DProj(tex0, shadowtexCoord0).r;

float normdist = (dist-near_clip)/(far_clip-near_clip); // normalize current distance by near/far clip as as the depth shader at the top

float shadowval = (normdist > shadowdepth) ? 0.5 : 1.0;

gl_FragColor = color * vec4(shadowval, shadowval, shadowval, 1.0);

]]>I tried making shadows a while ago, and did exactly the same thing as you.

(Computing the transformation matrix and passing it into the shader)

The missing clue was the: Inverse Viewmatrix of the camera to get the sm coordinates right.

A helpful resource hereby was a pdf called “SM_RTR.pdf”. It’s the top hit on google.

(Adding the direct link seems to be a problem)

You can also have a look at my attempt here:

http://cycling74.com/forums/topic.php?id=40620

I only did the transformation matrix with lua, as I do not speak java.

You can have a look at it inside the “TransformationMatrices” subpatcher.

I had previously convinced myself that I can just use a saved matrix multiplication of the 1st pass (bias * perspective * glulookat) against the 2nd pass fragment being rendered. That was wrong; you are correct. The nugget of info that I didn’t understand was that when I retrieve gl_ModelViewMatrix in the 2nd pass vertex shader, that OpenGL has already combined the current primitive’s Model *and* the current camera View into a single gl_ModelViewMatrix. I wrongly thought the camera’s simulated movement (that inverse you can get from glulookat) was combined within the Projection matrix (it’s not).

gluperspective -> projection matrix

glulookat -> camera’s contribution into the modelview matrix

gltranslate,scale,rotate -> model’s contribution into the modelview matrix

So to isolate just the 2nd pass primitive’s Model matrix, I need the inverse of the 2nd pass’s camera’s View (aka its contribution into the 2nd passes modelview matrix). That should get the matrix stack back to just the Model of the 2nd pass vertex which I can then transform with the previously saved matrix from pass 1.

Do you agree with this thinking?

]]>I got the inverse cameraview matrix from the anim.node connected to the camera. (gettransform or getinvtransform)

Then matrix-multiplied (inside or before the shader)

vec4 tempPos = gl_ModelViewMatrix * gl_Vertex; //Pass2 Transform.

tempPos = InvVmatrix * tempPos; //Multiplied with the inverse viewmatrix. Which was my missing clue.

ShadowC = MVPmatrix * tempPos; //Then the transformation matrix from pass1 => shadowmap texture coordinates.

Which seems to work.

Most times I had was glitchy stuff on screen. I had with the wrong order of multiplying the matrices. ^^