hi all,
i just try to get a propper shadowmapping in my game.
I copyed all the logik from a other example that works fine …
but as a result the shadow is moving strangly with the player/mouse movment …
So i´m quite sure this a matrix math problem … but i just can´t see whats wron with my calc.
I guess aPicture will not help her, so i made a small video:
As the complete script would be to long, ill try to show the important points in the right order.
// Frame Start
1. Load identyty for all matrix variables that are used in the frame
2. Bind my Shadowmap Framebuffer
3. Set Perspectiv for ‘Light World’:
setPerspectiv( ShadowMapSize, ShadowMapSize);
>> here is the function
void setPerspectiv(int Width, int Height)
{
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 60.0, float(Width) / float(Height), 1.0f, 100.0f );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
4. Save Light-Project Matrix :
glGetFloatv( GL_PROJECTION_MATRIX , (GLfloat*)&m_LightProjection );
5. Set Camera to Light View:
gluLookAt( 10.0f, 5.0f, 10.0f,
2.0f, 2.0f, 2.0f,
0.0, 1.0, 0.0 );
6. Save Light View Matrix:
glGetFloatv( GL_MODELVIEW_MATRIX , (GLfloat*)&m_LightView );
7. Set Perspectiv to Playes World :
setPerspectiv( CurrentWidth, CurrentHeight );
8. Set Camera to Player 3rd Person Vie:
gluLookAt( xpos-float(sin(yrotrad)*8.0), (ypos+float(sin(xrotrad)*18.0)*yMultiplyer)+8.4f, zpos+float(cos(yrotrad)*8.0),
xpos, ypos+4.4f, zpos,
0.0, 1.0, 0.0 );
9. Save Player View Matrix:
glGetFloatv( GL_MODELVIEW_MATRIX , (GLfloat*)&m_View );
10. Invert Player View Matrix:
bool inverting = InvertMatrix( (GLfloat*)&m_View.m[0][0] , (GLfloat*)&mViewInv.m[0][0] );
>> i just copyed this function from gluInverMatrix();
11. Calculate the ShadowTexture Matrix:
// Formular >> mTextureMatrix = m_BiasMatrix * m_LightProjection * m_LightView * mViewInv;
Matrix3DMultiply( &tmpMatrix , &m_BiasMatrix , &m_LightProjection );
Matrix3DMultiply( &tmpMatrix , &tmpMatrix , &m_LightView );
Matrix3DMultiply( &tmpMatrix , &tmpMatrix , &mViewInv );
mTextureMatrix = tmpMatrix;
// basis matrix looks like this:
Matrix3D m_BiasMatrix = {0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f};
12. Use Shader Programm and Set Uniforms:
glUseProgram(ProgramId);
glUniformMatrix4fv( s_u_TexProjectionMatrix, 1, GL_FALSE, (GLfloat*)&mTextureMatrix );
glActiveTexture ( GL_TEXTURE2 );
glBindTexture( GL_TEXTURE_2D , m_uiShadowMapTexture );
glUniform1i ( s_s_ShadowTexture, 2 );
glUniform1i ( s_u_shadowUse, 1 );
13. Draw Models like this:
// enable vertex attrib, set AttribPointers
// bind other textures
glPushMatrix();
// do translate and rotate with: glTranslatef() , glRotatef()
// get modelView matrix to shader
glGetFloatv( GL_MODELVIEW_MATRIX , this->modellMatrix );
glUniformMatrix4fv( this->m_u_modelMatrixLoc, 1, GL_FALSE, (GLfloat*)&this->modellMatrix );
glPopMatrix();
// get perspectiv matrix to shader
glGetFloatv( GL_PROJECTION_MATRIX , this->projectMatrix );
glUniformMatrix4fv( this->m_u_perspectMatrixLoc, 1, GL_FALSE, (GLfloat*)&this->projectMatrix );
// draw it
glDrawArrays( GL_TRIANGLES, 0, this->VertexCount ); // this->VertexCount
14. Use Data in Vertex Shader:
attribute vec4 in_Position;
attribute vec3 in_Normal;
attribute vec2 in_TextCoord;
uniform mat4 pers_Matrix;
uniform mat4 model_Matrix;
uniform highp mat4 TexProjectionMatrix;
uniform sampler2D s_mainTexture;
uniform vec3 LightDirection;
uniform bool shadowUse;
varying vec3 interp_Normal;
varying vec2 interp_TextCoord;
varying mat4 tmp_matrix;
varying highp vec4 projCoord;
varying float LightIntensity;
varying float doFragmentCalc;
void main(void)
{
if( shadowUse )
{
highp vec4 modelViewPos = model_Matrix * vec4( in_Position.xyz , 1.0 );
projCoord = TexProjectionMatrix * modelViewPos;
}
interp_Normal = in_Normal ;
interp_TextCoord = in_TextCoord ;
gl_Position = pers_Matrix * model_Matrix * in_Position ;
// Simple diffuse lighting in model space
LightIntensity = dot( in_Normal, -LightDirection ) + 0.4;
}
15. Use Data in Fragment Shader:
uniform mat4 pers_Matrix;
uniform mat4 model_Matrix;
uniform sampler2D s_mainTexture;
uniform sampler2D s_specTexture;
uniform highp sampler2D s_ShadowTexture;
uniform bool specTextureInUse;
uniform bool shadowUse;
varying vec4 interp_Normal;
varying vec2 interp_TextCoord;
varying mat4 tmp_matrix;
varying highp vec4 projCoord;
varying float LightIntensity;
varying float doFragmentCalc;
void main(void)
{
lowp float val = 1.0;
if( shadowUse )
{
// Subtract a small magic number to account for floating-point error
highp float comp = ( projCoord.z / projCoord.w ) - 0.03;
highp float depth = texture2DProj( s_ShadowTexture, projCoord ).r;
//val = (comp <= depth ? 1.0 : 0.4 ); // this fails because of wrong values i guess
val = ( depth > 0.83 ? 1.0 : 0.4 ); // << so just show the shadow texture
}
gl_FragColor = texture2D( s_mainTexture, interp_TextCoord ) * LightIntensity * val ;
gl_FragColor.a = 1.0;
if( specTextureInUse )
gl_FragColor.rgb += ( texture2D( s_specTexture, interp_TextCoord ).r / 5 ) * LightIntensity;
}
You can see the result of all this in the video …
I´m very shure its just a math miss-calculation …
This keeps me busy now for some time … pls give me a hint what i need to change …
Thanx very mutch !!!
uwi