Godot Version
4.4
Question
I am currently working on a dithering shader that takes 2x2 or 4x4 chunks of a texture and applies bayer matrix dithering to them. Basically each chunk depending on the level of dithering will make certain pixels in it transparent. I want to be able to let users pass in a point, preferably a world point but a local point would also work, and based on the point apply a certain level of dithering for each chunk.
The problem I’m running into is that it’s kinda tough working with points and translating them into UV points in a texture. I’ve found that multiplying or diving by TEXTURE_PIXEL_SIZE or SCREEN_PIXEL_SIZE can convert them between UV positions between 0.0 and 1.0 to one based on pixel count but the issue I’m running into is how to figure out where a world point is on a texture in the shader code.
“chunk” is the size in pixels of the chunks, (2x2 chunks would use 2, 4x4 chunks use 4, etc.) and dither_point is the value passed in. Currently it’s set to take in a local position from the Node however the issue I ran into with that is that it will only work if the pivot of the node is in the upper left corner of the texture.
void fragment() {
...
// Calculates the center point of the chunk that the current fragment is in
vec2 chunk_position = UV - mod(UV, TEXTURE_PIXEL_SIZE * float(chunk)) + (TEXTURE_PIXEL_SIZE * float(chunk) / 2.0);
switch (dither_type) {
case 0: // FLAT
...
case 2: // POINT
vec2 chunk_point = chunk_position / TEXTURE_PIXEL_SIZE;
vec2 point_dif = chunk_point - dither_point;
float length_from_point = sqrt(pow(point_dif.x, 2.0) + pow(point_dif.y, 2.0));
COLOR.a = is_fragment_transparent(fragment_dither, clamp(length_from_point / dither_point_radius, 0.0, 1.0)) ? COLOR.a : 0.0;
break;
}
}