1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include "sky_frag.h"
const char* shader_sky_frag = "precision highp float; \n"
" \n"
"varying vec2 vUv; \n"
" \n"
"uniform float time; // seconds, for slow cloud drift \n"
"uniform float horizon; // screen-space y of the water horizon (~0.5) \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"
"float fbm(vec2 p) { \n"
" float v = 0.0; \n"
" float amp = 0.5; \n"
" for (int i = 0; i < 4; i++) { \n"
" v += amp * valueNoise(p); \n"
" p *= 2.0; \n"
" amp *= 0.5; \n"
" } \n"
" return v; \n"
"} \n"
" \n"
"const vec3 SKY_HORIZON = vec3(0.80, 0.88, 0.98); // matches water horizon fade \n"
"const vec3 SKY_TOP = vec3(0.22, 0.48, 0.86); // deeper zenith blue \n"
"const vec3 CLOUD_COLOR = vec3(1.00, 0.98, 0.95); // white, slightly warm \n"
" \n"
"const float DEPTH_BIAS = 0.05; // caps frequency at the horizon (larger = gentler shrink) \n"
"const float CLOUD_FREQ = 2.7; // overall cloud scale (larger = more, smaller clouds) \n"
"const float X_STRETCH = 0.35; // < 1 stretches clouds horizontally -> wispy \n"
"const float CLOUD_THRESH = 0.55; // coverage cutoff; higher = sparser sky \n"
"const float CLOUD_SOFT = 0.22; // edge softness of the cloud mask \n"
"const float CLOUD_OPACITY = 0.85; // max cloud whiteness \n"
"const float DRIFT_SPEED = 0.03; // slow lateral drift (noise units / sec) \n"
"const float H_FADE = 0.12; // band over which clouds fade in above horizon \n"
" \n"
"void main() { \n"
" // Height above the water horizon: 0 at the waterline, (1 - horizon) at the top. \n"
" float above = max(vUv.y - horizon, 0.0); \n"
" \n"
" // Vertical gradient. \n"
" float g = clamp(above / (1.0 - horizon), 0.0, 1.0); \n"
" vec3 col = mix(SKY_HORIZON, SKY_TOP, pow(g, 0.75)); \n"
" float haze = 1.0 - smoothstep(0.0, 0.35, g); \n"
" col += vec3(0.06, 0.04, 0.00) * haze; \n"
" \n"
" // Flat cloud-ceiling perspective: distance along the view ~ 1/above, so \n"
" // features shrink AND compress vertically toward the horizon. \n"
" float depth = 1.0 / (above + DEPTH_BIAS); \n"
" vec2 q; \n"
" q.x = (vUv.x - 0.5) * depth; \n"
" q.y = depth; \n"
" \n"
" vec2 p = vec2(q.x * X_STRETCH, q.y) * CLOUD_FREQ; \n"
" p.x += time * DRIFT_SPEED; \n"
" \n"
" float n = fbm(p); \n"
" float cloud = smoothstep(CLOUD_THRESH, CLOUD_THRESH + CLOUD_SOFT, n); \n"
" \n"
" // Fade clouds into the haze right at the horizon. \n"
" cloud *= smoothstep(0.0, H_FADE, above); \n"
" \n"
" col = mix(col, CLOUD_COLOR, cloud * CLOUD_OPACITY); \n"
" \n"
" gl_FragColor = vec4(col, 1.0); \n"
"} \n"
" \n";
|