Created
May 20, 2024 04:24
-
-
Save IsukyPohlo/5190a1fe741c58b6c06b61fac9815624 to your computer and use it in GitHub Desktop.
Godot shader, tested on 4.2.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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