My water shader and pixelation shader don't play nice together. Can someone tell me why?

Godot Version

v4.4.1.stable.official.49a5bc7b6

Question

I made a retro pixelation shader that is just a camera filter to bitcrush the color, and reduce the pixel count in front of the camera. It's applied as a mesh insatance in front of the camera. Then I made a simple visual shader for water, super simple just a just a fragment shader with 2 scrolling noise textures. Both run fine on there own, but when in the same scene, they bug out and either don't show the water, or show the water but throw the camera around. I am very new to shaders (and godot for that matter) and I can't figure out what i'm doing wrong. I've included a clip of whats happening on my youtube. Any help, even if it's just telling me this is user error will be appreciated.

Are you using screen texture in the filter shader?

yes, I’m using it for the grabbing the size of the screen, and then again for the vec4 color to crush the colors into a more reduced pallet.

shader_type spatial;
render_mode unshaded;

#HERE uniform sampler2D screen_texture : hint_screen_texture, repeat_disable;
uniform float pixel_size : hint_range(0.0, 20.0, 1.0);
uniform float levels : hint_range(0.0, 100.0, 1.0);
uniform vec2 gamma;

void vertex() {
POSITION = vec4(VERTEX.xy, 1.0, 1.0);
}

void fragment() {
#HERE vec2 tex_size = vec2(textureSize(screen_texture, 0));
vec2 pixel_count = tex_size / (pixel_size * 2.0);
vec2 pixelated_uv = floor(SCREEN_UV * pixel_count) / pixel_count;

AND HERE vec4 color = texture(screen_texture, pixelated_uv);

color.rgb = pow(color.rgb, vec3(gamma.x));

float grayscale = max(color.r, max(color.g, color.b));
float lower = floor(grayscale * levels) / levels;
float higher = ceil(grayscale * levels) / levels;

float lower_diff = abs(lower - grayscale);
float higher_diff = abs(higher - grayscale);

float level = lower_diff < higher_diff ? lower : higher;
float adjustment = level / grayscale;

color.rgb *= adjustment;
color.rgb = pow(color.rgb, vec3(gamma.y));

ALBEDO = color.rgb;
ALPHA = color.a;

}

Screen texture is captured after the opaque rendering pass and before the transparent pass. Since the water presumably renders in the transparent pass - it won’t be rendered into the screen texture.

1 Like