2
\$\begingroup\$

i need some help with shadow mapping (directional light) in opengl 3.3 and GLSL. The problem is that the shadows are not displayed correctly over de 3d models and primitives:

This is the code that generate the shadow matrix an shaders source:

void shadow::calculateShadowMatrixFromLightPointOfView(vector3f lightPosition, vector3f lightDirection)
{
//this method, only bind the frame buffer:
//glBindFramebuffer(GL_FRAMEBUFFER, uiFramebuffer);
fboShadowMap.bindFramebuffer();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


//this method only bind the shader
m_shader.bindShader();

float rangeX = globalData::windowWidth;
float rangeY = globalData::windowHeight;

m_ProjectionMatrix =  glm::ortho<float>(-rangeX,rangeX,-rangeY,rangeY, 0.05f,400.0);

m_currentLigthPosition = glm::lookAt(
glm::vec3(lightPosition.x,lightPosition.y,lightPosition.z),
glm::vec3(
lightDirection.x,
lightDirection.y,
lightDirection.z
),
glm::vec3(0,1,0)
);

glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);


mDepthBiasMVP = biasMatrix * m_ProjectionMatrix * m_currentLigthPosition;


}

This creates the frame buffer:

bool frameBuffer::createFrameBufferWithTexture(int a_iWidth, int a_iHeight )
{
if(uiFramebuffer != 0)return false;

glGenFramebuffers(1, &uiFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, uiFramebuffer);

tFramebufferTex.createEmptyTexture(a_iWidth, a_iHeight, GL_RGB);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tFramebufferTex.getTextureID(), 0);

iWidth = a_iWidth;
iHeight = a_iHeight;

return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;

}

The a_iWidth and a_iHeight integers are 1024.

This creates the texture:

unsigned int CTexture::createTexture(int w,int h,bool isDepth)
{
glGenTextures(1,&uiTexture);
glBindTexture(GL_TEXTURE_2D,uiTexture);
glTexImage2D(GL_TEXTURE_2D,0,(!isDepth ? GL_RGBA8 : GL_DEPTH_COMPONENT),w,h,0,(isDepth ? GL_DEPTH_COMPONENT : GL_RGBA),GL_FLOAT,NULL);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

int i;
i=glGetError();
if(i!=0)
{
cout << "Error happened while loading the texture: " << i << "\n";
}
glGenSamplers(1, &uiSampler);
return uiTexture;
}

isDepth variable, is true when i use this function to construct de framebuffer.

Then in the shaders i use for shadows:

VERTEX SHADER:

#version 330 core                                                    

// Input vertex data, different for all executions of this shader.   
layout(location = 0) in vec3 inPosition;                             

// Values that stay constant for the whole mesh.                     
uniform mat4 depthMVP;                                               

void main(){                                                         
gl_Position = depthMVP*vec4(inPosition.xyz,1.0f);                
}                                                                    

FRAGMENT SHADER:

version 330 core

// Output data                                                      
layout(location = 0) out float fragmentdepth;                       

void main(){                                                        
fragmentdepth = gl_FragCoord.z;                                 
}                                                                   

Finally to render shadow in the "world", i use this shaders:

VERTEX SHADER:

#version 330                                                                

uniform mat4 projectionMatrix;                                              
uniform mat4 modelViewMatrix;                                               
uniform mat4 normalMatrix;                                                  
uniform mat4 modelMatrix;                                                   


uniform mat4 DepthBiasMVP;                                              
smooth out vec4 ShadowCoord;                                            


layout (location = 0) in vec3 inPosition;                                   
layout (location = 1) in vec2 inCoord;                                      
layout (location = 2) in vec3 inNormal;                                     

smooth out vec2 texCoord;                                                   
smooth out vec3 vNormal;                                                    
smooth out vec3 vEyeSpacePos;                                               
smooth out vec3 vWorldPos;                                                  

uniform float objOpacity;                                                   
smooth out float fObjOpacity;                                                                           
uniform vec3 objColor;                                                      
smooth out vec3 vObjColor;                                                  


void main()                                                                 
{                                                                           
vec4 vEyeSpacePosVertex = modelViewMatrix*vec4(inPosition, 1.0);        
gl_Position = projectionMatrix*vEyeSpacePosVertex;                      
texCoord = inCoord;                                                     
vec4 vRes = normalMatrix*vec4(inNormal, 0.0);                           
vNormal = vRes.xyz;                                                     
vEyeSpacePos = vEyeSpacePosVertex.xyz;                                  
vec4 vWorldPosVertex = modelMatrix*vec4(inPosition, 1.0);               
vWorldPos = vWorldPosVertex.xyz;                                        

ShadowCoord = DepthBiasMVP * vWorldPosVertex;                           


fObjOpacity = objOpacity;                                                   
vObjColor = objColor;                                                       

}   

FRAGMENT SHADER

#version 330                                                                

smooth in vec2 texCoord;                                                    
smooth in vec3 vNormal;                                                     
smooth in vec3 vEyeSpacePos;                                                
smooth in vec3 vWorldPos;                                                   

smooth in vec3 vObjColor;                                                   
smooth in float fObjOpacity;                                                
struct material 
{ 
float specularIntensity; 
float specularPower; 
}; 
uniform material m_material;                                                    

out vec4 outputColor;                                                       


uniform sampler2D gSampler;                                                 
vec4 totalLight = vec4(0.0,0.0,0.0,0.0);                                    
float visibility = 1.0f;                                                    


struct DirectionalLight                                                             
{                                                                                   
vec3 vColor;                                                                        
vec3 vPosition;                                                                     
vec3 vDirection;                                                                    
float fAmbientIntensity;                                                            
float fStrength;                                                                    
};                                                                                  


vec4 getDirectionalLightColor(DirectionalLight dirLight, vec3 vNormal)              
{                                                                                   
float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -dirLight.vDirection));  
return vec4(dirLight.vColor*(dirLight.fAmbientIntensity+fDiffuseIntensity)*dirLight.fStrength, 1.0);     
}

uniform DirectionalLight sunLight;  

uniform sampler2D shadowMap;                                                 
smooth in vec4 ShadowCoord;                                                  
vec2 poissonDisk[16] = vec2[]( 
vec2( -0.94201624, -0.39906216 ), 
vec2( 0.94558609, -0.76890725 ), 
vec2( -0.094184101, -0.92938870 ), 
vec2( 0.34495938, 0.29387760 ), 
vec2( -0.91588581, 0.45771432 ), 
vec2( -0.81544232, -0.87912464 ), 
vec2( -0.38277543, 0.27676845 ), 
vec2( 0.97484398, 0.75648379 ), 
vec2( 0.44323325, -0.97511554 ), 
vec2( 0.53742981, -0.47373420 ), 
vec2( -0.26496911, -0.41893023 ), 
vec2( 0.79197514, 0.19090188 ), 
vec2( -0.24188840, 0.99706507 ), 
vec2( -0.81409955, 0.91437590 ), 
vec2( 0.19984126, 0.78641367 ), 
vec2( 0.14383161, -0.14100790 ) 
);


float getVisibility(sampler2D shadowMap, vec4 vShadowCoord)     
{                                                               
float visibility = 1.0;                                     
float bias = 0.005;                                         

if(vShadowCoord.w > 0.0)
{
vec3 ShadowMapTexCoordProj = vShadowCoord.xyz / vShadowCoord.w;

if(ShadowMapTexCoordProj.x >= 0.0 && ShadowMapTexCoordProj.x < 1.0 &&
ShadowMapTexCoordProj.y >= 0.0 && ShadowMapTexCoordProj.y < 1.0 &&
ShadowMapTexCoordProj.z >= 0.0 && ShadowMapTexCoordProj.z < 1.0)
{                                                           
for (int i=0;i<4;i++)                                       
{                                                           
int index = i;
vec4 vShadowSmooth = vec4(ShadowMapTexCoordProj.x + poissonDisk[index].x/800.0, ShadowMapTexCoordProj.y + poissonDisk[index].y/600.0, (ShadowMapTexCoordProj.z-bias)/1.0, 1.0);
float fSub = texture(shadowMap, vShadowSmooth.st).r; 
visibility -= 0.1*(1.0-fSub);
}  
}
}    


return visibility;
}   

void main()                                                                 
{                                                                           
vec3 vNormalized = normalize(vNormal);                                  

totalLight += getDirectionalLightColor(sunLight, vNormal);                      


visibility =  getVisibility(shadowMap, ShadowCoord);         

vec4 vTexColor = texture2D(gSampler, texCoord);                         
vTexColor.a = fObjOpacity;                                              
vec4 vMixedColor = vTexColor*vec4(vObjColor,1.0);                       
outputColor = vec4(vMixedColor*totalLight*visibility);                  

}

When i see the scene, i get this results:

https://www.youtube.com/watch?v=6uS-f7qhWMI&feature=youtu.be

As you can see in the video, the objects are not affected for the shadows in the right way. All the objects are dark.

This is the order in wich the scene is rendered:

glViewport(0, 0, 1024, 1024);

//this function are described above
m_shadows->calculateShadowMatrixFromLightPointOfView(
dirLight->getPosition(),
dirLight->getDirection()
);

//render objects

glViewport(0, 0, globalData::windowWidth, globalData::windowHeight);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

//render objects

i dont know what is wrong, i read a lot of tutorials but the result is always wrong.

thank you for your help.

\$\endgroup\$
0
\$\begingroup\$

I found the solution: in the fragment shader in the shadow function it should be:

if(fSub<vShadowSmooth.z){
          visibility -= 0.1*(1.0-fSub);

          }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.