Hi, in the meantime I actually came up with a solution that almost works properly :

First I have a simple shader for my sprite where I give it a heighmap. Depending on the color of each pixel in the heightmap, I use the HDR value of that pixel to pass the height information onto another full-screen shader.
I'm sorry if my code is not super clean, I pretty much got my implementation to work by trial and error.
shader_type canvas_item;
uniform sampler2D heightmap;
void fragment(){
vec4 heightmap_tex = texture(heightmap, UV));
if(heightmap_tex.a > 0.9){
// I'am adding 1.0 * h to to that pixel's color, where h
// is the height of that pixel on the heightmap
COLOR = texture(TEXTURE, UV) + vec4(1.0, 1.0, 1.0, 0.0) * (heightmap_tex.r * 255.0 + 1.0);
} else {
COLOR = texture(TEXTURE, UV);
}
}
Then my screen shader knows that if a pixels'color is greater than 1.0, it means it has some height.
shader_type canvas_item;
uniform float xyangle;
uniform float zangle;
void fragment(){
bool isinshade = false;
float dist;
float height;
float lookupheight;
float traceheight;
vec4 col;
//first I calculate the height of the current pixel
col = texture(SCREEN_TEXTURE, SCREEN_UV);
height = col.r;
if(height < 1.0){height = 0.0;}
height = round(height);
//then I look at some pixels in a given direction
for(int i = 0; i < 100; i ++){
//distance of the pixel I'm looking at
dist = SCREEN_PIXEL_SIZE.x * float(i)*2000.0;
//UV of that pixel on screen
float lookupx =SCREEN_UV.x + (0.001) * (-4.0) * dist ;
float lookupy =SCREEN_UV.y + (0.001) * 0.0 * dist ;
//Height of that pixel
lookupheight = texture(SCREEN_TEXTURE, vec2(lookupx, lookupy)).r;
if(lookupheight < 1.0){lookupheight = 0.0;}
lookupheight = round(lookupheight);
//If that pixel's height is greater than the height of my current pixel
if(lookupheight > height){
//I calculate the height that that pixel should be if it was to draw a shadow
//on my current pixel
traceheight = dist * tan(zangle) + height;
if(traceheight < 1.0){traceheight = 0.0;}
traceheight = round(traceheight);
//If the height of that pixel and the height it needs to be are close enough
//then my current pixel needs to be shaded
if(abs(traceheight-lookupheight) < 4.0){
isinshade = true;
}
}
}
//Now I'm juste resetting the pixel's color to it's real value
if(col.r > 1.0 || col.g > 1.0 || col.b > 1.0){
col.r = mod(col.r, 1.0);
col.g = mod(col.g, 1.0);
col.b = mod(col.b, 1.0);
COLOR = col;
isinshade = false;
}
if(isinshade){
COLOR = col - vec4(0.2, 0.15, 0.15, 0.0);
} else {
COLOR = col;
}
}
Ok so as I said, using those two shaders I get some decent results but I still have two major problems:
First you may have notice that I'm not using xyangle in my screen shader. It's because whenever I use :
float lookupx =SCREENUV.x + (0.001) * cos(xyangle) * dist ;
float lookupy =SCREENUV.y + (0.001) * sin(xyangle) * dist ;
it causes ugly artifacts:

I'm pretty sure it has something to do with an imprecision caused by the floating values of the sin() and cos() but I'm not exactly sure.
So does anyone know how I could fix those ?
Second since I'm using SCREEN_TEXTURE to read the height value of each pixel, I can't access the height of a pixel off screen. So whenever a sprite is partly outside the screen, its shadow gets partly cutted out. So is there a way I could access pixels slightly off screen in my second shader ?
Thanks a lot for reading me !