From c8938fe29132a11126013ed1b010c3092f5645e4 Mon Sep 17 00:00:00 2001 From: Matt Kosarek Date: Wed, 8 Jul 2026 09:07:55 -0400 Subject: feature: improved summer scene --- themes/src/shaders/water_frag.cpp | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 themes/src/shaders/water_frag.cpp (limited to 'themes/src/shaders/water_frag.cpp') diff --git a/themes/src/shaders/water_frag.cpp b/themes/src/shaders/water_frag.cpp new file mode 100644 index 0000000..91c50f9 --- /dev/null +++ b/themes/src/shaders/water_frag.cpp @@ -0,0 +1,66 @@ +#include "water_frag.h" + +const char* shader_water_frag = "precision highp float; \n" +" \n" +"varying vec3 vWorldPos; \n" +"varying vec3 vNormal; \n" +" \n" +"uniform vec3 cameraPos; \n" +"uniform vec3 sunDir; // normalized direction from the water toward the sun \n" +"uniform vec3 sunColor; \n" +"uniform float time; \n" +" \n" +"float hash(vec2 p) { \n" +" p = fract(p * vec2(123.34, 456.21)); \n" +" p += dot(p, p + 45.32); \n" +" return fract(p.x * p.y); \n" +"} \n" +" \n" +"float valueNoise(vec2 p) { \n" +" vec2 i = floor(p); \n" +" vec2 f = fract(p); \n" +" float a = hash(i); \n" +" float b = hash(i + vec2(1.0, 0.0)); \n" +" float c = hash(i + vec2(0.0, 1.0)); \n" +" float d = hash(i + vec2(1.0, 1.0)); \n" +" vec2 u = f * f * (3.0 - 2.0 * f); \n" +" return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); \n" +"} \n" +" \n" +"void main() { \n" +" vec3 N = normalize(vNormal); \n" +" vec3 V = normalize(cameraPos - vWorldPos); \n" +" \n" +" // Fresnel (Schlick). \n" +" float f0 = 0.02; \n" +" float fres = f0 + (1.0 - f0) * pow(1.0 - max(dot(N, V), 0.0), 5.0); \n" +" \n" +" // Refraction: depth-tinted water body, wobbled by the surface normal. \n" +" float depth01 = clamp((vWorldPos.z + 350.0) / 400.0, 0.0, 1.0); \n" +" float wob = (N.x + N.z) * 0.5; \n" +" vec3 shallow = vec3(0.10, 0.55, 0.60); \n" +" vec3 deep = vec3(0.02, 0.14, 0.28); \n" +" vec3 refractCol = mix(shallow, deep, clamp(depth01 + wob * 0.15, 0.0, 1.0)); \n" +" \n" +" // Reflection: sky gradient + reflected sun glow + broken-up specular glitter. \n" +" vec3 R = reflect(-V, N); \n" +" vec3 skyHorizon = vec3(0.80, 0.88, 0.98); \n" +" vec3 skyTop = vec3(0.30, 0.55, 0.95); \n" +" float skyT = clamp(R.y * 2.0, 0.0, 1.0); \n" +" vec3 reflectCol = mix(skyHorizon, skyTop, skyT); \n" +" \n" +" float sunAmt = max(dot(R, sunDir), 0.0); \n" +" reflectCol += sunColor * pow(sunAmt, 8.0) * 0.6; \n" +" float sparkle = valueNoise(vWorldPos.xz * 0.5 + vec2(time * 1.3, time * 0.7)); \n" +" float spec = pow(sunAmt, 200.0) * smoothstep(0.55, 0.9, sparkle); \n" +" reflectCol += sunColor * spec * 4.0; \n" +" \n" +" vec3 color = mix(refractCol, reflectCol, fres); \n" +" \n" +" // Horizon haze: hide the far straight edge of the plane by fading to sky. \n" +" float horizonFade = clamp((vWorldPos.z + 350.0) / 90.0, 0.0, 1.0); \n" +" color = mix(skyHorizon, color, horizonFade); \n" +" \n" +" gl_FragColor = vec4(color, 1.0); // opaque -> occludes the sun below the waterline \n" +"} \n" +" \n"; -- cgit v1.2.1