     int type;
 };
 uniform Light light;
+struct Shadow
+{
+    mat4 matrixPV;
+    float bias;
+    float strength;
+    sampler2D texture;
+};
+uniform Shadow shadow;
 
 in vec2 v2f_uv;
 in mat4 v2f_matrixInvPV;

        lightDir = normalize(-light.direction);
    }
    else {
        lightDir = light.position - reconstructWorldPosition();
        lightDistance = length(lightDir);
        lightDir = lightDir / lightDistance;    //normalize
    }

            //Compute diffuse
            diffuse = light.intensity * light.color * NdotL * attenuation;
        }

        if (shadow.strength > 0) {
            //Adjust bias by slope
            float bias = shadow.bias * tan(acos(NdotL));
            bias = clamp(bias, 0.0002, 0.01);
            
            vec4 shadowPosition = shadow.matrixPV * vec4(worldPosition, 1);
            vec2 samplePosition = shadowPosition.xy / shadowPosition.w;
            float occluderDepth = texture(shadow.texture, samplePosition).r;
            if (occluderDepth < (shadowPosition.z - bias) / shadowPosition.w) {
                float l = 0;
                //Fade out directional light at the edges of the shadowmap
                if (light.type == 0) {
                    l = smoothstep(0.9, 1.0, length(2 * samplePosition - vec2(1)));
                }
                shadowStrength = (1 - l) * shadow.strength;
            }
        }
    }

    //Combine light components
    vec3 lighting = diffuse * (1 - shadowStrength) + ambient;

    out_color = texColor * lighting;
    // out_color = abs(texture(tex_normal, v2f_uv).rgb * 2 - vec3(1));
}
