ok, I think I got it.
I just needed to transform the clip space shadow coords to ndc, then to tex coords.
#version 330 core
layout(binding=0) uniform sampler2D texture0;
uniform vec3 light_pos, spot_dir;
uniform float radius, spot_exponent, spot_cos_cutoff;
in vec3 normal;
in vec3 vs_pos;
in vec4 ls_pos;
out vec4 color;
void main()
{
vec3 n = normal;
vec3 l = light_pos - vs_pos;
float d = length(l);
l = normalize(l);
float att = (1 + d / radius);
att = 1.0 / ( att * att );
float n_dot_l = dot(n, l);
if(n_dot_l > 0)
{
vec3 h = 0.5 * (l + normalize(-vs_pos));
float n_dot_h = max(dot(n, h), 0);
float spot_effect = dot(-l, spot_dir);
if(spot_effect > spot_cos_cutoff)
{
spot_effect = pow( spot_effect, spot_exponent );
att = spot_effect / att + 1;
}
att -= 1;
vec4 shadow_coord = ls_pos / ls_pos.w; //convert to ndc
shadow_coord = shadow_coord * 0.5 + 0.5; //scale, bias to [0...1]
float depth = texture( texture0, shadow_coord.xy ).x;
att *= depth < shadow_coord.z - 0.005 ? 0 : 1; //add bias to get rid of shadow acne
color += vec4(vec3((0.1 + n_dot_l + pow(n_dot_h, 20)) * att), 1);
}
color.xyz = pow(color.xyz, vec3(1/2.2));
//color = vec4(1);
}

Find content
Not Telling