Skip to content

Instantly share code, notes, and snippets.

@IsukyPohlo
Created May 20, 2024 04:24
Show Gist options
  • Save IsukyPohlo/5190a1fe741c58b6c06b61fac9815624 to your computer and use it in GitHub Desktop.
Save IsukyPohlo/5190a1fe741c58b6c06b61fac9815624 to your computer and use it in GitHub Desktop.
Godot shader, tested on 4.2.2
// Basically just added the vertex part from the 2nd one into the 1st one
// https://godotshaders.com/shader/toon-water-shader/
// https://godotshaders.com/shader/orthogonal-camera-view-water-shader/
shader_type spatial;
const float SMOOTHSTEP_AA = 0.01;
uniform sampler2D surfaceNoise;
uniform sampler2D distortNoise;
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
uniform float beer_factor = 0.8;
uniform float foam_distance = 0.01;
uniform float foam_max_distance = 0.4;
uniform float foam_min_distance = 0.04;
uniform vec4 foam_color: source_color = vec4(1.0);
uniform vec2 surface_noise_tiling = vec2(1.0, 4.0);
uniform vec3 surface_noise_scroll = vec3(0.03, 0.03, 0.0);
uniform float surface_noise_cutoff: hint_range(0, 1) = 0.777;
uniform float surface_distortion_amount: hint_range(0, 1) = 0.27;
uniform vec4 _DepthGradientShallow: source_color = vec4(0.325, 0.807, 0.971, 0.725);
uniform vec4 _DepthGradientDeep: source_color = vec4(0.086, 0.407, 1, 0.749);
uniform float _DepthMaxDistance: hint_range(0, 1) = 1.0;
uniform float _DepthFactor = 1.0;
uniform float height_scale = 0.5;
varying vec2 tex_position;
uniform sampler2D normalmap;
const float wave_scale = 0.4; //maybe related to fish scales?
const float wave_scale2 = 0.3;
const float wave_scale3 = 0.5;
const float wave_scale4 = 0.6;
const float wave_pow = 0.65; //yes, waves power
const float wave_pow2 = 4.0; //so much wave power that aquaman is jealous
varying vec2 noiseUV;
varying vec2 distortUV;
varying vec3 viewNormal;
vec4 alphaBlend(vec4 top, vec4 bottom)
{
vec3 color = (top.rgb * top.a) + (bottom.rgb * (1.0 - top.a));
float alpha = top.a + bottom.a * (1.0 - top.a);
return vec4(color, alpha);
}
float wave(vec2 position){ //hello *wave back*
position += texture(surfaceNoise, position / 64.0).x * 2.0 - 1.0; // Check this
vec2 wv = 1.0 - abs(sin(position));
return pow(1.0 - pow(wv.x * wv.y, wave_pow), wave_pow2);
}
float height(vec2 position, float time) { //time, yeah, definitely that
float d = wave((position + time) * wave_scale) * 0.3;
d += wave((position - time) * wave_scale2) * 0.3; //so friendly with all the waving.. is it too much tho??
d += wave((position + time) * wave_scale3) * 0.2;
d += wave((position - time) * wave_scale4) * 0.2;
return d;
}
void vertex() {
viewNormal = (MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
noiseUV = UV * surface_noise_tiling;
distortUV = UV;
// Get the current vertex position
vec3 pos = VERTEX;
// Get the height of the terrain at this position
float k = height(pos.xz, TIME);
// Set the Y position of the vertex to the terrain height
VERTEX.y = k * height_scale;
// Calculate the normal vector using nearby terrain heights
NORMAL = normalize(vec3(
k - height(pos.xz + vec2(0.1, 0.0), TIME),
0.1,
k - height(pos.xz + vec2(0.0, 0.1), TIME)
));
// Apply the normal map to the normal vector
NORMAL = normalize(texture(normalmap, tex_position).rgb * 2.0 - 1.0 + NORMAL);
}
void fragment(){
// https://www.youtube.com/watch?v=Jq3he9Lbj7M
float depthVal = texture(DEPTH_TEXTURE, SCREEN_UV).r;
float depth = PROJECTION_MATRIX[3][2] / (depthVal + PROJECTION_MATRIX[2][2]);
depth = depth + VERTEX.z;
depth = exp(-depth * beer_factor);
depth = 1.0 - depth;
// Still unsure how to get properly the NORMAL from the camera
// This was generated by ChatGPT xD
vec4 view_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depthVal, 1.0);
view_pos /= view_pos.w;
vec3 existingNormal = normalize(cross( dFdx(view_pos.xyz), dFdy(view_pos.xyz)));
float normalDot = clamp(dot(existingNormal.xyz, viewNormal), 0.0, 1.0);
float foamDistance = mix(foam_max_distance, foam_min_distance, normalDot);
float foamDepth = clamp(depth / foamDistance, 0.0, 1.0);
float surfaceNoiseCutoff = foamDepth * surface_noise_cutoff;
vec4 distortNoiseSample = texture(distortNoise, distortUV);
vec2 distortAmount = (distortNoiseSample.xy * 2.0 -1.0) * surface_distortion_amount;
vec2 noise_uv = vec2(
(noiseUV.x + TIME * surface_noise_scroll.x) + distortAmount.x ,
(noiseUV.y + TIME * surface_noise_scroll.y + distortAmount.y)
);
float surfaceNoiseSample = texture(surfaceNoise, noise_uv).r;
float surfaceNoiseAmount = smoothstep(surfaceNoiseCutoff - SMOOTHSTEP_AA, surfaceNoiseCutoff + SMOOTHSTEP_AA, surfaceNoiseSample);
float waterDepth = clamp(depth / _DepthMaxDistance, 0.0, 1.0) * _DepthFactor;
vec4 waterColor = mix(_DepthGradientShallow, _DepthGradientDeep, waterDepth);
vec4 surfaceNoiseColor = foam_color;
surfaceNoiseColor.a *= surfaceNoiseAmount;
vec4 color = alphaBlend(surfaceNoiseColor, waterColor);
ALBEDO = color.rgb;
ALPHA = color.a;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment