I'm coming to you because I'm totally stuck on a shader I'm trying to do.
Basically I need a shader which diffuses light according to a given position (the light is in fact only the normal color of the screen which darkens according to the distance compared to the radius).
That I managed to do, but comes the moment of collisions with the walls and I never manage to have the expected result, either the light stops or continues its path a bit anyhow, or it doesn't. there is no more light at all...
So I totally rewrote this shader several times, removed some useless parts in the collision to read it better, etc. but still the same problems... (the wall collisions is actually a canvas containing white pixels for empty areas and black pixels for obstacles)
If anyone has done this before and could point me in the right direction or tell me where I'm wrong that would be great!
(Knowing that I'm still new to shaders, maybe I don't know some things that would be useful to me in this case)
Here is where I am currently (simplified version and comment)
Code: Select all
extern number light_radius;
extern vec2 light_pos;
extern Image collision_mask;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) {
vec4 pixel = Texel(texture, texture_coords);
// Calculation of the distance between the position of the light and the current position on the screen
number distance = length(light_pos - screen_coords);
// If the distance is greater than the radius of the light, do not display light
if (distance > light_radius) {
pixel.a = 0.2;
return pixel;
}
// Start raycasting from the current position on the screen
vec2 ray_direction = normalize(light_pos - screen_coords);
vec2 current_position = screen_coords;
// Repeat until the ray reaches the position of the light or encounters an obstacle
while (current_position != light_pos) {
current_position += ray_direction; // Move ray
// Check if there is an obstacle at this location in the collision mask
if (Texel(collision_mask, current_position).r == 0) {
break; // S'il y a un obstacle, arrêter de raycaster
}
}
// If the ray reaches the position of the light, show the normal color
if (current_position == light_pos) {
return Texel(texture, texture_coords) * color;
}
// Otherwise, display a dark pixel
pixel.a = 0.2;
return pixel;
}