• 3D
  • Godot water shader

Is the looping fine in game and just the gif causing the jump cut(I'm going to guess so)?

I had gotten too busy with other things and it dropped off of my radar however I'll attach the unfinished water shader I was putting together for you a month or so back.

No vertex waveform in here but you could maybe combine parts of these two shaders for something quite interesting. Consider this too MIT.

Thanks Megalomaniak. This one is free for anyone, it looks good and it's a good starter.

The concern with vertex based is there is no LOD, if your water plane is big this will decrease the frame rate.

    vec2 UVText = UV; 
    UVText.x = (UV.x + (TIME * XspeedMultiplier)) * UVscaling; 
    UVText.y = (UV.y + (TIME * XspeedMultiplier)) * UVscaling; 
    
    vec3 normalNoiseText = texture(normalNoise,UVText).rgb ;  

I'm working on other things and a basic water shader will do the job. Another effect using blending two normal maps with lerp and having both using UV shift could produce something interesting.

shader_type spatial;
 
uniform float UVscaling = 10;
uniform float UVscaling2 = 10;

uniform float XspeedMultiplier = 0.001;
uniform float YspeedMultiplier = 0.001;
 
uniform float XspeedMultiplier2 = 0.001;
uniform float YspeedMultiplier2 = 0.001;


uniform sampler2D normal1; 
uniform sampler2D normal2; 

uniform vec3 colorWater;
uniform float roughnessValue =0.1;
uniform float metalnessValue =0.7;

void vertex() { 
}

void fragment(){

vec2 UVText = UV;
vec2 UVText2  = UV;

UVText.x = (UV.x + (sin(TIME * XspeedMultiplier))) * UVscaling; 
UVText.y = (UV.y + (cos(TIME * XspeedMultiplier))) * UVscaling; 

UVText2.x = (UV.x + (sin(TIME * XspeedMultiplier2))) * UVscaling2; 
UVText2.y = (UV.y + (cos(TIME * XspeedMultiplier2))) * UVscaling2; 

vec3 normal1Text = texture(normal1,UVText).rgb ;  

vec3 normal2Text = texture(normal2,UVText2).rgb ;  

vec3 normalBlend =  mix(normal1Text,normal2Text, sin(TIME)); 

vec3 normalOutput = clamp (normalBlend, 0.1, 1); 
//NORMALMAP_DEPTH = 0.5; 

ALBEDO = colorWater; 
ROUGHNESS =roughnessValue; 
METALLIC = metalnessValue ; 
NORMALMAP = normalize( normalOutput);

}

Well, since we don't have geometry shaders we can't do LOD in shaders, however you could add parameters to the generation function built upon the SurfaceTool to tessellate at varying detail density.

Well, since we don't have geometry shaders we can't do LOD in shaders

It is possible to have LOD in shaders (such as waving water) without relying on geometry shaders, but it is more difficult. For example, the Cube 2 engine (used in the open source games Sauerbraten, Red Eclipse and Tesseract) splits water areas into several chunks with varying level of detail depending on the distance to the camera.

I'm not very good at shaders, there is more skilled people than me. I think i will put on github two versions : Water plane shader, as above code working with planes, you can use it for sea, lakes, rivers , fountains. Ocean, the same version with added vertex animation

For vertex animation a good trick can be to have ocean water tiles join together using LOD. Distant flat tiles would be planes with four vertices and a simple shader, while nearest ones would be vertex grid with the ocean shader. I've seen that effect on Just Cause 3 game, where distant water tiles was visible and using a shader less complex when flying high. For those nearest tiles i think there must be a way to know the vertex squared distance to camera, to only do vertex animation on nearest vertex.

@Calinou you sure its in shader and not handled before shader though? Something like ray marching and distance fields?

@Megalomaniak said: @Calinou you sure its in shader and not handled before shader though? Something like ray marching and distance fields?

You are right, it's not handled by the shader in this case. It is probably slower but it should work well enough for most use cases.

Yeah, I agree that LOD can be done(and is a useful thing to-do ofc.), my only point was that it can't be done in shader without geometry shaders. :)