I have a Godot CanvasItem shader that is assigned to the material of a specific tile in a TileMap. In the shader, I need to know the position of a light relative to the bottom of the tile.
I am computing the bottom right corner like this:
varying vec2 bottom_right_corner;
void vertex() {
vec2 world_vertex_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
bottom_right_corner = floor(world_vertex_position / 32.0 + 1.0) * 32.0;
}
void light() {
// How to compare bottom_right_corner.y with LIGHT_POSITION.y ?
}
I think now I need to apply some transformation to these coordinates so that I can compare them with LIGHT_POSITION
, but I'm not sure which.
How can I perform this comparison?
I found the solution. We need to multiply LIGHT_POSITION
by the inverse of CANVAS_MATRIX
. Here's what I ended up with:
shader_type canvas_item;
uniform ivec2 tile_size = ivec2(32, 32); // Size of the tiles
varying flat ivec2 bottom_left_corner;
varying flat ivec2 bottom_right_corner;
varying mat4 inv_canvas_matrix;
void vertex() {
inv_canvas_matrix = inverse(CANVAS_MATRIX);
vec2 world_vertex_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
bottom_right_corner = (ivec2(round(world_vertex_position / vec2(tile_size))) + 1) * tile_size;
bottom_left_corner = bottom_right_corner + ivec2(-tile_size.x, 0);
}
void light() {
// Default light calculation
vec4 color = texture(TEXTURE, UV);
LIGHT = vec4(color.rgb * LIGHT_COLOR.rgb * LIGHT_ENERGY, LIGHT_COLOR.a);
// Compute the light position in world space
ivec2 world_light_position = ivec2((inv_canvas_matrix * vec4(LIGHT_POSITION, 1.0)).xy);
// Now you can compare world_light_position with bottom_right_corner or bottom_left_corner
// ...
}