1+ #version 460 core
2+
3+ precision highp float ;
4+
5+ #include < flutter/ runtime_effect.glsl>
6+
7+ uniform vec2 uSize;
8+ uniform float uTime;
9+ uniform float uRotation;
10+
11+ out vec4 fragColor;
12+
13+ const int NUM_STEPS = 16 ;
14+ const float PI = 3.141592 ;
15+ const float EPSILON = 1e-3 ;
16+ #define EPSILON_NRM (0.08 / uSize.x)
17+
18+ const int ITER_GEOMETRY = 3 ;
19+ const int ITER_FRAGMENT = 5 ;
20+ const float SEA_HEIGHT = 0.6 ;
21+ const float SEA_CHOPPY = 4.0 ;
22+ const float SEA_SPEED = 0.8 ;
23+ const float SEA_FREQ = 0.16 ;
24+ const vec3 SEA_BASE = vec3 (0.0 ,0.09 ,0.18 );
25+ #define SEA_TIME (1.0 + uTime * SEA_SPEED)
26+ const mat2 octave_m = mat2 (1.2 , 1.2 , - 1.2 , 1.6 );
27+ vec3 SEA_WATER_COLOR = vec3 (0.8 ,0.9 ,0.6 )* 0.6 ;
28+
29+ /*
30+ * "Seascape" by Alexander Alekseev aka TDM - 2014
31+ * License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
32+ * Adopted to Flutter to by @reNotANumber
33+ */
34+ mat3 fromEuler(vec3 ang) {
35+ vec2 a1 = vec2 (sin (ang.x),cos (ang.x));
36+ vec2 a2 = vec2 (sin (ang.y),cos (ang.y));
37+ vec2 a3 = vec2 (sin (ang.z),cos (ang.z));
38+ mat3 m;
39+ m[0 ] = vec3 (a1.y* a3.y+ a1.x* a2.x* a3.x,a1.y* a2.x* a3.x+ a3.y* a1.x,- a2.y* a3.x);
40+ m[1 ] = vec3 (- a2.y* a1.x,a1.y* a2.y,a2.x);
41+ m[2 ] = vec3 (a3.y* a1.x* a2.x+ a1.y* a3.x,a1.x* a3.x- a1.y* a3.y* a2.x,a2.y* a3.y);
42+ return m;
43+ }
44+ float hash( vec2 p ) {
45+ float h = dot (p,vec2 (127.1 ,311.7 ));
46+ return fract (sin (h)* 43758.5453123 );
47+ }
48+ float noise( in vec2 p ) {
49+ vec2 i = floor ( p );
50+ vec2 f = fract ( p );
51+ vec2 u = f* f* (3.0 - 2.0 * f);
52+ return - 1.0 + 2.0 * mix ( mix ( hash( i + vec2 (0.0 ,0.0 ) ),
53+ hash( i + vec2 (1.0 ,0.0 ) ), u.x),
54+ mix ( hash( i + vec2 (0.0 ,1.0 ) ),
55+ hash( i + vec2 (1.0 ,1.0 ) ), u.x), u.y);
56+ }
57+
58+ float diffuse(vec3 n,vec3 l,float p) {
59+ return pow (dot (n,l) * 0.4 + 0.6 ,p);
60+ }
61+
62+ float specular(vec3 n,vec3 l,vec3 e,float s) {
63+ float nrm = (s + 8.0 ) / (PI * 8.0 );
64+ return pow (max (dot (reflect (e,n),l),0.0 ),s) * nrm;
65+ }
66+
67+ float sea_octave(vec2 uv, float choppy) {
68+ uv += noise(uv);
69+ vec2 wv = 1.0 - abs (sin (uv));
70+ vec2 swv = abs (cos (uv));
71+ wv = mix (wv, swv, wv);
72+ return pow (1.0 - pow (wv.x * wv.y, 0.65 ), choppy);
73+ }
74+
75+ float map(vec3 p) {
76+ float freq = SEA_FREQ;
77+ float amp = SEA_HEIGHT;
78+ float choppy = SEA_CHOPPY;
79+ vec2 uv = p.xz; uv.x *= 0.75 ;
80+
81+ float d, h = 0.0 ;
82+ for (int i = 0 ; i < ITER_GEOMETRY; i++ ) {
83+ d = sea_octave((uv+ SEA_TIME)* freq,choppy);
84+ d += sea_octave((uv- SEA_TIME)* freq,choppy);
85+ h += d * amp;
86+ uv *= octave_m; freq *= 1.9 ; amp *= 0.22 ;
87+ choppy = mix (choppy,1.0 ,0.2 );
88+ }
89+ return p.y - h;
90+ }
91+
92+ float map_detailed(vec3 p) {
93+ float freq = SEA_FREQ;
94+ float amp = SEA_HEIGHT;
95+ float choppy = SEA_CHOPPY;
96+ vec2 uv = p.xz; uv.x *= 0.75 ;
97+
98+ float d, h = 0.0 ;
99+ for (int i = 0 ; i < ITER_FRAGMENT; i++ ) {
100+ d = sea_octave((uv+ SEA_TIME)* freq,choppy);
101+ d += sea_octave((uv- SEA_TIME)* freq,choppy);
102+ h += d * amp;
103+ uv *= octave_m; freq *= 1.9 ; amp *= 0.22 ;
104+ choppy = mix (choppy,1.0 ,0.2 );
105+ }
106+ return p.y - h;
107+ }
108+
109+
110+ vec3 getSkyColor(vec3 e) {
111+ e.y = (max (e.y,0.0 )* 0.8 + 0.2 )* 0.8 ;
112+ return vec3 (pow (1.0 - e.y,2.0 ), 1.0 - e.y, 0.6 + (1.0 - e.y)* 0.4 ) * 1.1 ;
113+ }
114+
115+ vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
116+ float fresnel = clamp (1.0 - dot (n, - eye), 0.0 , 1.0 );
117+ fresnel = min (fresnel * fresnel * fresnel, 0.5 );
118+
119+ vec3 reflected = getSkyColor(reflect (eye, n));
120+ vec3 refracted = SEA_BASE + diffuse(n, l, 80.0 ) * SEA_WATER_COLOR * 0.12 ;
121+
122+ vec3 color = mix (refracted, reflected, fresnel);
123+
124+ float atten = max (1.0 - dot (dist, dist) * 0.001 , 0.0 );
125+ color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;
126+
127+ color += specular(n, l, eye, 600.0 * inversesqrt (dot (dist,dist)));
128+
129+ return color;
130+ }
131+
132+
133+ vec3 getNormal(vec3 p, float eps) {
134+ vec3 n;
135+ n.y = map_detailed(p);
136+ n.x = map_detailed(vec3 (p.x+ eps,p.y,p.z)) - n.y;
137+ n.z = map_detailed(vec3 (p.x,p.y,p.z+ eps)) - n.y;
138+ n.y = eps;
139+ return normalize (n);
140+ }
141+
142+ float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {
143+ float tm = 0.0 ;
144+ float tx = 1000.0 ;
145+ float hx = map(ori + dir * tx);
146+ if (hx > 0.0 ) {
147+ p = ori + dir * tx;
148+ return tx;
149+ }
150+ float hm = map(ori);
151+ for (int i = 0 ; i < NUM_STEPS; i++ ) {
152+ float tmid = mix (tm, tx, hm / (hm - hx));
153+ p = ori + dir * tmid;
154+ float hmid = map(p);
155+ if (hmid < 0.0 ) {
156+ tx = tmid;
157+ hx = hmid;
158+ } else {
159+ tm = tmid;
160+ hm = hmid;
161+ }
162+ if (abs (hmid) < EPSILON) break ;
163+ }
164+ return mix (tm, tx, hm / (hm - hx));
165+ }
166+
167+ vec3 getPixel(in vec2 coord, float time) {
168+ vec2 uv = coord / uSize.xy;
169+ uv = uv * 2.0 - 1.0 ;
170+ uv.x *= uSize.x / uSize.y;
171+
172+ // ray
173+ vec3 ang = vec3 (sin (time* 3.0 )* 0.1 ,sin (time)* 0.2 + 0.3 ,time);
174+ vec3 ori = vec3 (0.0 ,3.5 ,time* 5.0 );
175+ vec3 dir = normalize (vec3 (uv.xy,- 2.0 )); dir.z += length (uv) * 0.14 ;
176+ dir = normalize (dir) * fromEuler(ang);
177+
178+ // tracing
179+ vec3 p;
180+ heightMapTracing(ori,dir,p);
181+ vec3 dist = p - ori;
182+ vec3 n = getNormal(p, dot (dist,dist) * EPSILON_NRM);
183+ vec3 light = normalize (vec3 (0.0 ,1.0 ,0.8 ));
184+
185+ // color
186+ return mix (
187+ getSkyColor(dir),
188+ getSeaColor(p,n,light,dir,dist),
189+ pow (smoothstep (0.0 ,- 0.02 ,dir.y),0.2 ));
190+ }
191+
192+ // vec3 getPixel(in vec2 coord, float time) {
193+ // vec2 uv = coord / uSize.xy;
194+ // uv = uv * 2.0 - 1.0;
195+ // uv.x *= uSize.x / uSize.y;
196+
197+ // float r = 1480.0;
198+
199+ // float t = uRotation;
200+
201+ // vec3 ang = vec3(0.0, 0.83, -t);
202+ // vec3 ori = vec3(r * sin(t), 178.5, time + r * cos(t));
203+ // vec3 dir = normalize(vec3(uv.xy, -2.0));
204+ // dir.z += length(uv) * 0.01;
205+ // dir = normalize(dir) * fromEuler(ang);
206+
207+ // vec3 p;
208+ // heightMapTracing(ori, dir, p);
209+ // vec3 dist = p - ori + vec3(0.0, 30.5, 0.0);
210+ // vec3 n = getNormal(p, dot(dist, dist) * EPSILON_NRM);
211+ // vec3 light = normalize(vec3(0.0, 1000.5, -1500)) * 0.96;
212+
213+ // vec3 color = mix(vec3(1), getSeaColor(p, n, light, dir, dist), pow(smoothstep(0.0, -0.02, dir.y), 0.2));
214+
215+ // float brightness = dot(color, vec3(0.299, 0.587, 0.114));
216+ // float highlightMask = pow(brightness, 2.5);
217+ // color = color + color * highlightMask * 2.5;
218+
219+ // return color;
220+ // }
221+
222+ void main() {
223+ float time = - uTime * 0.3 ;
224+ vec2 fragCoord = FlutterFragCoord().xy * vec2 (1.0 , - 1.0 ) + vec2 (0.0 , uSize.y);
225+ vec3 color = getPixel(fragCoord, time);
226+ fragColor = vec4 (pow (color, vec3 (0.85 )), 1.0 );
227+
228+ }
0 commit comments