Hello,
i am trying to implement shadow Mapping.
Its working great for Direct light and Points lights.
my problem is, i am trying to implement this in 1 shader, but if i have both funktions in the shader implementing my mesh is not anymore displaying.
I have trying a lot but the only thing i have found out that is the two texture()funktion are the problem if i have only one in the shader its working great.
her is my code:
Fragment Shader:
uniform sampler2D shadowMap[5];
uniform samplerCube cubeMap[5];
//Light uniform
uniform struct Light {
int type;
//position
vec3 position;
vec3 direction;
//color
vec3 ambient;
vec3 diffuse;
vec3 specular;
//attenuation
float constant;
float linear;
float quadratic;
//spot Light
float spotCutOff;
float spotOuterCutOff;
bool isSpot;
//shadow
mat4 lightSpaceMatrix;
int shadowNR;
};
uniform Light lights[100];
uniform struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform Material material;
uniform vec3 color;
uniform vec3 viewPos;
uniform int numLights;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
float DirectShadowCalculation(vec4 fragPosLightSpace,vec3 norm,vec3 lightPos, int i)
{
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// Transform to [0,1] range
//projCoords = projCoords * 0.5 + 0.5;
// Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
float closestDepth1 = texture(shadowMap[i], projCoords.xy).r;
// Get depth of current fragment from light's perspective
float currentDepth1 = projCoords.z;
// Check whether current frag pos is in shadow
float shadow1 = currentDepth1 > closestDepth1 ? 1.0 : 0.0;
return shadow1;
}
float PointShadowCalculation(vec3 fragPos,vec3 lightdir,int i)
{
// Get vector between fragment position and light position
vec3 fragToLight = fragPos - lightdir;
// Use the light to fragment vector to sample from the depth map
float closestDepth2 = texture(cubeMap[i], fragToLight).r;
//return closestDepth;
// It is currently in linear range between [0,1]. Re-transform back to original value
closestDepth2 *= 300;
// Now get current linear depth as the length between the fragment and light position
float currentDepth2 = length(fragToLight);
// Now test for shadows
float bias = 0.05;
float shadow2 = currentDepth2-bias < closestDepth2 ? 1.0 : 0.0;
return shadow2;
}
void main() {
vec3 result = vec3(0.f,0.f,0.f);
vec3 normal = normalize(Normal);
for(int i=0; i < numLights;i++){
vec3 lightColor = vec3(0.4);
// Ambient
vec3 ambient =0.2 * lights[i].ambient;
// Diffuse
vec3 lightDir = normalize(lights[i].position - FragPos);
//vec3 lightDir = normalize(-lights[i].direction);
float diff = max(dot(lightDir, normal), 0.0);
vec3 diffuse =0.5 * diff * lights[i].diffuse;
// Specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 256);
vec3 specular = 0.5 * spec * lights[i].specular;
// Calculate shadow
float shadow = 0.0f;
if(lights[i].type != 1){
vec4 FragPosLightSpace = lights[i].lightSpaceMatrix * vec4(FragPos,1.0f);
shadow = DirectShadowCalculation(FragPosLightSpace,normal,lights[i].position,lights[i].shadowNR);
}else{
//shadow = PointShadowCalculation(FragPos,lights[i].position,lights[i].shadowNR);//<---------if i command mash is not displaying
}
//shadow = min(shadow, 0.75); // reduce shadow strength a little: allow some diffuse/specular light in shadowed regions
result += (ambient + (1.0-shadow) * (diffuse + specular)) * color;
}
gl_FragColor = vec4(result,1.0f);
}
Binding Lights to shader:
//binding shader
...
for(;lights[j] != NULL; j++){
if(lights[j]->getMode() != PointLight){
sprintf_s(name,50,"shadowMap[%d]",directShadowNR);
lights[j]->get_Shadowbuffer()->BindForReading(shaderUSE->programId(),j,name);
lights[j]->shaderLights(j, directShadowNR, shaderUSE);
directShadowNR++;
}else{
sprintf_s(name,50,"cubeMap[%d]",cubeShadowNR);
lights[j]->get_Shadowbuffer()->BindForReading(shaderUSE->programId(),j+6,name);
lights[j]->shaderLights(j, cubeShadowNR, shaderUSE);
cubeShadowNR++;
}
}
shaderUSE->setUniformValue("numLights",j);
...
//draw mesh
Binding Framebuffer texture(BindForReading()):
void GLFrameBuffer::BindForReading(GLuint program, int textureNumber,const char* name)
{
GLuint texID = glGetUniformLocation(program, name);
glUniform1i(texID, textureNumber);
glActiveTexture(GL_TEXTURE0 + textureNumber);
glBindTexture(this->m_type, this->m_bufferTexture); // m_type for cubemaps: GL_TEXTURE_CUBE_MAP and Texture:GL_TEXTURE_2D
}
in Fragment shader the problem is
this is working
if(lights[i].type != 1){
vec4 FragPosLightSpace = lights[i].lightSpaceMatrix * vec4(FragPos,1.0f);
shadow = DirectShadowCalculation(FragPosLightSpace,normal,lights[i].position,lights[i].shadowNR);
}else{
//shadow = PointShadowCalculation(FragPos,lights[i].position,lights[i].shadowNR);
}
this is also working
if(lights[i].type != 1){
vec4 FragPosLightSpace = lights[i].lightSpaceMatrix * vec4(FragPos,1.0f);
//shadow = DirectShadowCalculation(FragPosLightSpace,normal,lights[i].position,lights[i].shadowNR);
}else{
shadow = PointShadowCalculation(FragPos,lights[i].position,lights[i].shadowNR);
}
this is not working
if(lights[i].type != 1){
vec4 FragPosLightSpace = lights[i].lightSpaceMatrix * vec4(FragPos,1.0f);
shadow = DirectShadowCalculation(FragPosLightSpace,normal,lights[i].position,lights[i].shadowNR);
}else{
shadow = PointShadowCalculation(FragPos,lights[i].position,lights[i].shadowNR);
}
if somthing not god explained or missing i will try to make it clear if you ask.
I hope you can help me with that problem.