Applying distortion to screen texture with semi-transparent albedo texture

Godot Version



I have a functional water shader that uses different noise textures to make the water texture move according to the noise maps. The issue is that this only modifies the given water texture, and I want it to distort everything behind the mesh as well. I already know how to achieve the effect individually, that is, without a mesh texture already applied:

The problem is that I don’t know how to achieve this distortion with the water texture applied. I tried different approaches, but I could only distort the water texture, and not the actual screen_texture

Here’s part of the shader code for the water:

void fragment() {
	//Set time variables to match the wave direction
	vec2 time  = (TIME *wave_direction) * time_scale;
	vec2 time2 = (TIME *wave_direction2) * time_scale;
	vec3 blend_normals = mix(texture(normal_map, UV + time).rgb, texture(normal_map2, UV + time2).rgb, 0.5);
	//Albedo vec3 conversion 
	vec3 albedo_text = texture(albedo, (UV+time) * vec2(3.0, 3.0)).rgb; //Last vec2 scales the texture
	ALBEDO = albedo_text*vec3(1.27, 1.1, 0.73); //Multiplied by a vec3, which basically changes the color (BLUE)

Not entirely sure what you want to accomplish.
A distorted water surface, on which the underlying objects/texture is shown distorted in the same way? Like having refraction?

There are a lot refraction turorials/how-tos out there (just google refraction+shader(+GODOT)).

Basically, i think its not (straight forwardly) possible to just change the screen texture from within the shader.

Instead, the SCREEN_TEXTURE value obtained at the distorted UV position is mixed into the ALBEDO of the current position, with a certain intensity.
So the basic idea, is doing:

ALBEDO = mix(ALBEDO, screen_texture(distorted_uv), intensity);

Thanks for the answer, I eventually got what I wanted by doing something similar to what you mentioned. The main problem I had is that I didn’t know how to mix both textures (forgot about mix()). Still, for a better result, I used a function to recreate image blending modes, specifically the overlay() blending mode