4
\$\begingroup\$

This is how it looks now:

enter image description here

enter image description here

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();


//I'M not sure if this is ok..
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::createFrameBufferForDepthShadow(int width, int height)
{
if(uiFramebuffer != 0)return false;

iWidth = width;
iHeight = height;
glBindRenderbuffer(GL_RENDERBUFFER, uiFramebuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);

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

tFramebufferTex.createTexture(width, height, true);

tFramebufferTex.setFiltering(TEXTURE_FILTER_MAG_NEAREST, TEXTURE_FILTER_MIN_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


glBindFramebuffer(GL_FRAMEBUFFER, uiFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tFramebufferTex.getTextureID(), 0);
glDrawBuffer(GL_NONE);

// Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    return false;
return true;
}

The width and height 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 windowWidth, float windowHeight)     
{   

float visibility = 1.0;          
float bias = 0.0012;                                         

for (int i=0;i<4;i++)
{
    int index = i;
    vec4 vShadowSmooth = vec4(vShadowCoord.x + poissonDisk[index].x/windowWidth, vShadowCoord.y + poissonDisk[index].y/windowHeight, (vShadowCoord.z)/vShadowCoord.w, 1.0);
    float fSub = texture(shadowMap, vShadowSmooth.st).r; 

    if(fSub<vShadowCoord.z-bias){
        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);                  

}

As you can see in the pictures, the shadow have these horrible "acne" and i don know how to avoid it.

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
\$\endgroup\$
1
  • \$\begingroup\$ ok, i fix the problem, the error may be caused by frame buffer and texture creation. \$\endgroup\$ Commented Dec 22, 2015 at 22:56

3 Answers 3

1
\$\begingroup\$

Shadow acne is a finicky thing to deal with sometimes. I would suggest double checking your projection matrix when filling the shadow map to make sure it is as "tight" as possible, that is its far plane as as close as possible.

This Microsoft page has a lengthy discussion on shadow acne and shadows in general, and how to fix it:

https://msdn.microsoft.com/en-us/library/windows/desktop/ee416324(v=vs.85).aspx

And another page I used when developing my shadows: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/

\$\endgroup\$
1
  • \$\begingroup\$ thank you, i saw this page but cant fix the problem yet \$\endgroup\$ Commented Nov 8, 2015 at 13:22
0
\$\begingroup\$

Those darker triangles seem to say that its possible you havent set your normals right. Please check your normals for the vertices

\$\endgroup\$
2
  • \$\begingroup\$ ok, i will check the normals and comment the results. Thanks. \$\endgroup\$ Commented Nov 8, 2015 at 13:20
  • \$\begingroup\$ no.. it doest fix the problem. :( \$\endgroup\$ Commented Dec 19, 2015 at 15:17
0
\$\begingroup\$

This helped me with my shadow acne, maybe it will work for you?

In the shadow fragment shader:

gl_FragDepth = gl_FragCoord.z;
gl_FragDepth += smoothstep(0.0f, 1.0f, (1.0f - gl_FragDepth));

I don't know why smoothstep made a difference, but it did.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .