• Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a \$50 Amazon gift card. Click here to get started!

# Shadow mapping orthographic directional light .w=1

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

3 replies to this topic

### #1polyfrag  Crossbones+   -  Reputation: 2241

Like
0Likes
Like

Posted 17 February 2014 - 11:18 PM

I'm using an orthographic projection matrix for the light and it doesn't seem correct unless in the depth vertex shader I set gl_Position.w = 1; (I just noticed in my other project that I had to set a drawing orthographic projection matrix gl_Position.w = 1; to make it pixel-perfect with the dimensions I specified when constructing the matrix, and that the shadow actually moved if I moved the light, which shouldn't happen for a directional/orthographic projection light, so I noticed today that I had to set gl_Position.w = 1; for the light orthographic matrix too.)

attribute vec4 position;

uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;

attribute vec2 texCoordIn0;
varying vec2 texCoordOut0;

void main(void)
{
gl_Position = projection * (view * (model * position));
gl_Position.w = 1;	// sun light is orthographic directional light
texCoordOut0 = texCoordIn0;
}



However that causes the shadow to show up wrong. lpos is the vertex in the light's clip-space on a range [0,1] (scaled by 0.5 and translated 0.5 for texture mapping).

void main(void)
{
//vec4 vpos = (view * (model * position));
vec4 vpos = model * position;
//vec4 vpos = position;
//vpos.w = 1;
lpos = lightMatrix * vpos;
lpos.w = 1;
gl_Position = projection * (view * (model * position));
//gl_Position.w = 1;


Setting lpos.w = 1 doesn't help.

void main (void)
{
//....

vec3 smcoord = lpos.xyz / lpos.w;
//vec3 smcoord = lpos.xyz;



Edited by polyfrag, 17 February 2014 - 11:30 PM.

### #2MJP  Moderators   -  Reputation: 14498

Like
1Likes
Like

Posted 17 February 2014 - 11:41 PM

Orthographic projection matrices typically use [0 0 0 1] was their last column (or row, if you're using column-major matrices) which means that the resulting w component should always be 1.0 provided that the w component of input vector is 1.0. If the w component isn't 1 (or very close to it), then it suggests that you may be doing something wrong when transforming your vertex position or creating your matrices.

### #3polyfrag  Crossbones+   -  Reputation: 2241

Like
0Likes
Like

Posted 17 February 2014 - 11:56 PM

Here's what I use.

Pretty sure this function is correct, and the problem is with postMultiply.


// http://www.songho.ca/opengl/gl_projectionmatrix.html
Matrix setorthographicmat(float l, float r, float t, float b, float n, float f)
{
float m[16];

#define M(row,col)  m[col*4+row]
M(0, 0) = 2 / (r - l);
M(0, 1) = 0;
M(0, 2) = 0;
M(0, 3) = 0;

M(1, 0) = 0;
M(1, 1) = 2 / (t - b);
M(1, 2) = 0;
M(1, 3) = 0;

M(2, 0) = 0;
M(2, 1) = 0;
M(2, 2) = -1 / (f - n);
//M(2, 2) = -2 / (f - n);
M(2, 3) = 0;

M(3, 0) = -(r + l) / (r - l);
M(3, 1) = -(t + b) / (t - b);
M(3, 2) = -n / (f - n);
//M(3, 2) = -(f + n) / (f - n);
M(3, 3) = 1;
#undef M

Matrix mat;
mat.set(m);

return mat;
}

void Matrix::postMultiply( const Matrix& matrix )
{
float newMatrix[16];

#if 0

const float *m1 = m_matrix, *m2 = matrix.m_matrix;

newMatrix[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2];
newMatrix[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2];
newMatrix[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2];
newMatrix[3] = 0;

newMatrix[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6];
newMatrix[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6];
newMatrix[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6];
newMatrix[7] = 0;

newMatrix[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10];
newMatrix[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10];
newMatrix[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10];
newMatrix[11] = 0;

newMatrix[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12];
newMatrix[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13];
newMatrix[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14];
newMatrix[15] = 1;

#else

const float *a = m_matrix, *b = matrix.m_matrix;

newMatrix[0]  = a[0] * b[0]  + a[4] * b[1]  + a[8] * b[2]   + a[12] * b[3];
newMatrix[1]  = a[1] * b[0]  + a[5] * b[1]  + a[9] * b[2]   + a[13] * b[3];
newMatrix[2]  = a[2] * b[0]  + a[6] * b[1]  + a[10] * b[2]  + a[14] * b[3];
newMatrix[3]  = a[3] * b[0]  + a[7] * b[1]  + a[11] * b[2]  + a[15] * b[3];

newMatrix[4]  = a[0] * b[4]  + a[4] * b[5]  + a[8] * b[6]   + a[12] * b[7];
newMatrix[5]  = a[1] * b[4]  + a[5] * b[5]  + a[9] * b[6]   + a[13] * b[7];
newMatrix[6]  = a[2] * b[4]  + a[6] * b[5]  + a[10] * b[6]  + a[14] * b[7];
newMatrix[7]  = a[3] * b[4]  + a[7] * b[5]  + a[11] * b[6]  + a[15] * b[7];

newMatrix[8]  = a[0] * b[8]  + a[4] * b[9]  + a[8] * b[10]  + a[12] * b[11];
newMatrix[9]  = a[1] * b[8]  + a[5] * b[9]  + a[9] * b[10]  + a[13] * b[11];
newMatrix[10] = a[2] * b[8]  + a[6] * b[9]  + a[10] * b[10] + a[14] * b[11];
newMatrix[11] = a[3] * b[8]  + a[7] * b[9]  + a[11] * b[10] + a[15] * b[11];

newMatrix[12] = a[0] * b[12] + a[4] * b[13] + a[8] * b[14]  + a[12] * b[15];
newMatrix[13] = a[1] * b[12] + a[5] * b[13] + a[9] * b[14]  + a[13] * b[15];
newMatrix[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15];
newMatrix[15] = a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15];

#endif

set( newMatrix );
}

Edited by polyfrag, 18 February 2014 - 12:10 AM.

### #4polyfrag  Crossbones+   -  Reputation: 2241

Like
0Likes
Like

Posted 18 February 2014 - 12:41 AM

I made a new function to use just for calculating  the light matrix

void Matrix::postMultiply2( const Matrix& matrix )
{
float newMatrix[16];

#if 1

const float *m1 = m_matrix, *m2 = matrix.m_matrix;

newMatrix[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2];
newMatrix[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2];
newMatrix[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2];
newMatrix[3] = 0;

newMatrix[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6];
newMatrix[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6];
newMatrix[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6];
newMatrix[7] = 0;

newMatrix[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10];
newMatrix[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10];
newMatrix[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10];
newMatrix[11] = 0;

newMatrix[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12];
newMatrix[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13];
newMatrix[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14];
newMatrix[15] = 1;

#else

const float *a = m_matrix, *b = matrix.m_matrix;

newMatrix[0]  = a[0] * b[0]  + a[4] * b[1]  + a[8] * b[2]   + a[12] * b[3];
newMatrix[1]  = a[1] * b[0]  + a[5] * b[1]  + a[9] * b[2]   + a[13] * b[3];
newMatrix[2]  = a[2] * b[0]  + a[6] * b[1]  + a[10] * b[2]  + a[14] * b[3];
newMatrix[3]  = a[3] * b[0]  + a[7] * b[1]  + a[11] * b[2]  + a[15] * b[3];

newMatrix[4]  = a[0] * b[4]  + a[4] * b[5]  + a[8] * b[6]   + a[12] * b[7];
newMatrix[5]  = a[1] * b[4]  + a[5] * b[5]  + a[9] * b[6]   + a[13] * b[7];
newMatrix[6]  = a[2] * b[4]  + a[6] * b[5]  + a[10] * b[6]  + a[14] * b[7];
newMatrix[7]  = a[3] * b[4]  + a[7] * b[5]  + a[11] * b[6]  + a[15] * b[7];

newMatrix[8]  = a[0] * b[8]  + a[4] * b[9]  + a[8] * b[10]  + a[12] * b[11];
newMatrix[9]  = a[1] * b[8]  + a[5] * b[9]  + a[9] * b[10]  + a[13] * b[11];
newMatrix[10] = a[2] * b[8]  + a[6] * b[9]  + a[10] * b[10] + a[14] * b[11];
newMatrix[11] = a[3] * b[8]  + a[7] * b[9]  + a[11] * b[10] + a[15] * b[11];

newMatrix[12] = a[0] * b[12] + a[4] * b[13] + a[8] * b[14]  + a[12] * b[15];
newMatrix[13] = a[1] * b[12] + a[5] * b[13] + a[9] * b[14]  + a[13] * b[15];
newMatrix[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15];
newMatrix[15] = a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15];

#endif

set( newMatrix );
}


Notice the switch #if is 1 in this one. And it seems to do the trick. Can anybody explain why this one works specifically for orthographic matrixes but not projection?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS