Multiple shadow maps from multiple light sources

Hi,

My engine has 3 lights. Directional lighting, point lights (max 4 in one frame) and a spot light. All of them are supposed to cast shadows (each will have a separate shadow map). So far I only had one shader that used all 3 lights but no shadows and another shader that only had directional lighting and shadows from a directional lighting shadow map.

Now I’m trying to combine it and I’m not sure how to do it. When should I take the shadow map into account ? And should I read all shadow maps at once or should I use each shadow map when calculating the light corresponding to it ?

vec3 calc_dir_light(const dir_light_t light, const lightdata_t lightdata)
{
    vec3 lightdir = normalize(-light.dir);
    //diffuse shading
    float diff = max(dot(lightdata.normal, lightdir), 0.0);
    //specular
    vec3 reflectdir = reflect(-lightdir, lightdata.normal);
    vec3 halfwaydir = normalize(lightdir + lightdata.viewdir);
    float spec = pow(max(dot(lightdata.normal, halfwaydir), 0.0), lightdata.matshine);
    //combine
    vec3 ambient = (light.ambi) * lightdata.pixdiff;
    vec3 diffuse = light.diff * diff;
    vec3 specular = light.spec * spec * lightdata.pixspec;
    return (ambient + lightdata.shadow * (diffuse + specular)) *  lightdata.pixdiff;
}

vec3 calc_point_light(const point_light_t light, const lightdata_t lightdata)
{
    vec3 lightdir = normalize(light.pos - lightdata.fragpos);
    //diffuse
    float diff = max(dot(lightdata.normal, lightdir), 0.0);
    //specular
    vec3 reflectdir = reflect(-lightdir, lightdata.normal);
    float spec = pow(max(dot(lightdata.viewdir, reflectdir), 0.0), lightdata.matshine);
    //attenuation
    float distance = length(light.pos - lightdata.fragpos);
    float attenuation = 1.0 / (light.constant + light.linear * distance +
                               light.quadratic * (distance * distance));

    //combine
    vec3 ambient = light.ambi * lightdata.pixdiff;
    vec3 diffuse = light.diff * diff;// * lightdata.pixdiff;
    vec3 specular = light.spec * spec * lightdata.pixspec;

    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;

    return (ambient + lightdata.shadow * (diffuse + specular)) *  lightdata.pixdiff;
}

vec3 calc_spot_light(const spot_light_t light, const lightdata_t lightdata)
{
    vec3 lightdir = normalize(light.pos - lightdata.fragpos);
    //diffuse
    float diff = max(dot(lightdata.normal, lightdir), 0.0);
    //specular
    vec3 reflectdir = reflect(-lightdir, lightdata.normal);
    float spec = pow(max(dot(lightdata.viewdir, reflectdir), 0.0), lightdata.matshine);
    //attenuation
    float distance = length(light.pos - lightdata.fragpos);
    float attenuation = 1.0 / (light.constant + light.linear * distance +
                               light.quadratic * (distance * distance));

    // spotlight intensity
    float theta = dot(lightdir, normalize(-light.dir));
    float epsilon = light.cutoff - light.outcutoff;
    float intensity = clamp((theta - light.outcutoff) / epsilon, 0.0, 1.0);

    //combine
    vec3 ambient = light.ambi * lightdata.pixdiff;
    vec3 diffuse = light.diff * diff;// * lightdata.pixdiff;
    vec3 specular = light.spec * spec * lightdata.pixspec;

    ambient *= attenuation * intensity;
    diffuse *= attenuation * intensity;
    specular *= attenuation * intensity;

    return (ambient + lightdata.shadow * (diffuse + specular)) *  lightdata.pixdiff;
}

This is what I have now and it sort of works, but I think the shadows are too dark even when there’s a very bright point light next to an object