• Advertisement
Sign in to follow this  

Shadow mapping orthographic directional light .w=1

This topic is 1434 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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). 

 

Heightmap vertex shader:

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.

 

Heightmap frag shader:

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

	vec3 smcoord = lpos.xyz / lpos.w;
	//vec3 smcoord = lpos.xyz;
	float shadow = max(0.6, 
		float(smcoord.z <= texture(shadowmap, smcoord.xy).x));
  	
Edited by polyfrag

Share this post


Link to post
Share on other sites
Advertisement

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.

Share this post


Link to post
Share on other sites

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
// http://www.scratchapixel.com/lessons/3d-advanced-lessons/perspective-and-orthographic-projection-matrix/orthographic-projection/
// http://www.opengl.org/discussion_boards/showthread.php/172280-Constructing-an-orthographic-matrix-for-2D-drawing
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

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement