I have a TileSet
and I'm trying to apply a custom Shader
and ShaderMaterial
to one of my tiles. However, it's not shading the right area. I'm a newbie to both Godot and game development, but everything I've read seems to indicate my code is correct.
shader_type canvas_item;
uniform vec2 points[3]; // Polygon points
uniform vec2 atlas_id; // atlas position within the TileSet
uniform vec2 tile_size = vec2(32.0, 32.0);
uniform vec4 modulate_color : source_color;
// code generated by Copilot
bool point_in_triangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) {
vec2 v0 = p2 - p0;
vec2 v1 = p1 - p0;
vec2 v2 = p - p0;
float dot00 = dot(v0, v0);
float dot01 = dot(v0, v1);
float dot02 = dot(v0, v2);
float dot11 = dot(v1, v1);
float dot12 = dot(v1, v2);
float invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (u >= 0.0) && (v >= 0.0) && (u + v < 1.0);
}
void fragment() {
vec2 top_left_px = atlas_id * tile_size;
vec2 pixel_coordinate = UV / TEXTURE_PIXEL_SIZE;
pixel_coordinate[0] = mod(pixel_coordinate[0], tile_size[0]);
vec2 relative_coord = pixel_coordinate - top_left_px;
// Check if the current fragment is inside the triangle
if (point_in_triangle(relative_coord, points[0], points[1], points[2])) {
COLOR *= modulate_color;
}
}
My TileSet's texture is 256x256 with tiles 32x32.
I'm trying to shade the triangles on the third row with my shader. This is the result of the above code.
For the life of me, I can't figure out what I'm doing wrong. If I had to guess, it's the calculation of vec2 pixel_coordinate = UV / TEXTURE_PIXEL_SIZE;
. I just don't understand why, and haven't found a good way to debug a shader without a debugger or printf.
When I hard-code the texture size, it works perfectly.
vec2 pixel_coordinate = UV * vec2(256.0, 256.0);
This is hardly ideal. I have made it a uniform, but that still means if I ever change my texture's size, I'll need to update every place that I use this shader. I'd still like a general answer.
Just disable texture padding in the TileSet configuration, shader is being applied to the original texture and is not aware of the padding, hence the weird scaling.