One commited on
Commit
db16d2d
·
verified ·
1 Parent(s): 3eb8245

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +26 -5
index.html CHANGED
@@ -170,6 +170,8 @@ function decode(code){
170
  return { peak, shape, rough: F32(F32(rg)/F32(15)), type, ramp, pk, sh, rg };
171
  }
172
 
 
 
173
  function landH(x, z){
174
  const cx = Math.floor(x/ICELL), cz = Math.floor(z/ICELL);
175
  // starting below sea level is what makes the depth readable: outside an island there is no
@@ -198,7 +200,13 @@ function landH(x, z){
198
  if(d > rr) continue;
199
  const k = F32(F32(1.0) - F32(F32(d)/F32(rr)));
200
  const nz = F32(F32(0.55) + F32(F32(0.45)*F32(p.rough)*lnoise(F32(F32(dx*f2) + F32((p.pk+p.sh+1)%16)), F32(F32(dz*f2) + F32((p.pk+p.sh+7)%16)))));
201
- const terr = (p.ramp > 0 ? Math.min(1, k/p.ramp) : Math.pow(k, p.shape)) * nz;
 
 
 
 
 
 
202
  h = Math.max(h, p.peak*terr - LAND.shelf); // the shelf is the shallow ring around an island
203
  }
204
  return h;
@@ -281,11 +289,21 @@ float landH(vec2 p){
281
  float rough = rg/15.0;
282
  float k = 1.0 - d/rr;
283
  float nz = 0.55 + 0.45*rough*lnoise(r*f2 + vec2(mod(pk+sh+1.0, 16.0), mod(pk+sh+7.0, 16.0)));
284
- float terr = (ramp > 0.0) ? min(1.0, k/ramp) * nz : pow(k, shape) * nz;
285
  h = max(h, peak*terr - 1.2);
286
  }
287
  return h;
288
  }
 
 
 
 
 
 
 
 
 
 
289
  `;
290
 
291
  /* ================= hull =================
@@ -481,7 +499,7 @@ void main(){
481
  vLand = land;
482
  vDepth = water - land; // depth of water over the seabed
483
  vEdge = edge;
484
- vNormal = waveN(w, uTime); // land normals come from the facets in the fragment stage
485
  vFoam = clamp((wake + hullFoam + popFoam) * (isLand ? 0.0 : 1.0), 0.0, 1.0);
486
  gl_Position = uProj * uView * vec4(wp, 1.0);
487
  }`, `#version 300 es
@@ -538,9 +556,12 @@ void main(){
538
  // mesh - a staircase on a 1 m grid. It is now an interpolated value, so the crossing is a line across
539
  // each facet that joins with its neighbours, and the narrow band between the two is blended instead of
540
  // switched.
 
 
 
541
  float t = clamp(smoothstep(-0.12, 0.12, vEdge), 0.0, 1.0);
542
- if(fn.y < 0.12) t = 1.0; // a facet this steep can only be a cliff face - the sea never gets that steep
543
- vec3 n = mix(wn, fn, t);
544
  if(n.y < 0.0) n = -n;
545
  vec3 col = mix(waterCol(wn), landCol(fn, max(vLand, 0.0)), t);
546
  float ndl = max(dot(n, LDIR), 0.0);
 
170
  return { peak, shape, rough: F32(F32(rg)/F32(15)), type, ramp, pk, sh, rg };
171
  }
172
 
173
+ // smoothstep on [0,1], every step rounded to float32 so the shader and the boat get the same number
174
+ function smooth01(u){ return F32(F32(F32(u)*F32(u))*F32(F32(3.0)-F32(F32(2.0)*u))); }
175
  function landH(x, z){
176
  const cx = Math.floor(x/ICELL), cz = Math.floor(z/ICELL);
177
  // starting below sea level is what makes the depth readable: outside an island there is no
 
200
  if(d > rr) continue;
201
  const k = F32(F32(1.0) - F32(F32(d)/F32(rr)));
202
  const nz = F32(F32(0.55) + F32(F32(0.45)*F32(p.rough)*lnoise(F32(F32(dx*f2) + F32((p.pk+p.sh+1)%16)), F32(F32(dz*f2) + F32((p.pk+p.sh+7)%16)))));
203
+ // A hard min at k = ramp is a crease, and where that crease meets the shoreline it reads as a
204
+ // corner. Easing it keeps the flat top - u is clamped to 1 over most of the radius - but rounds the
205
+ // shoulder. The shader does the same thing, so the boat still sits on the ground it is drawn on.
206
+ const u = F32(F32(k)/F32(p.ramp));
207
+ let s = 1.0;
208
+ if(u <= 0.0) s = 0.0; else if(u >= 1.0) s = 1.0; else s = smooth01(u);
209
+ const terr = F32(F32(p.ramp > 0 ? s : Math.pow(k, p.shape)) * F32(nz));
210
  h = Math.max(h, p.peak*terr - LAND.shelf); // the shelf is the shallow ring around an island
211
  }
212
  return h;
 
289
  float rough = rg/15.0;
290
  float k = 1.0 - d/rr;
291
  float nz = 0.55 + 0.45*rough*lnoise(r*f2 + vec2(mod(pk+sh+1.0, 16.0), mod(pk+sh+7.0, 16.0)));
292
+ float terr = (ramp > 0.0) ? smoothstep(0.0, 1.0, k/ramp) * nz : pow(k, shape) * nz; // eased shoulder, mirrored in the JS copy
293
  h = max(h, peak*terr - 1.2);
294
  }
295
  return h;
296
  }
297
+ // Land normal from the height field itself rather than from the facet drawn. Bilinear interpolation
298
+ // between lattice points is planar, so each cell is a flat sheet and the facet normal makes every quad
299
+ // read as its own tile. Sampling the field either side of the point gives a normal that varies
300
+ // continuously, which is what stops the islands looking like polygons.
301
+ vec3 landN(vec2 p){
302
+ float e = 0.25;
303
+ float hx = (landH(p + vec2(e, 0.0)) - landH(p - vec2(e, 0.0))) / (2.0*e);
304
+ float hz = (landH(p + vec2(0.0, e)) - landH(p - vec2(0.0, e))) / (2.0*e);
305
+ return normalize(vec3(-hx, 1.0, -hz));
306
+ }
307
  `;
308
 
309
  /* ================= hull =================
 
499
  vLand = land;
500
  vDepth = water - land; // depth of water over the seabed
501
  vEdge = edge;
502
+ vNormal = isLand ? landN(w) : waveN(w, uTime); // only land vertices pay for the extra samples
503
  vFoam = clamp((wake + hullFoam + popFoam) * (isLand ? 0.0 : 1.0), 0.0, 1.0);
504
  gl_Position = uProj * uView * vec4(wp, 1.0);
505
  }`, `#version 300 es
 
556
  // mesh - a staircase on a 1 m grid. It is now an interpolated value, so the crossing is a line across
557
  // each facet that joins with its neighbours, and the narrow band between the two is blended instead of
558
  // switched.
559
+ // The normal comes from the height field, not from the facet, so land shades continuously across the
560
+ // mesh instead of one flat tile per quad. fn is still used, but only to decide which material a facet
561
+ // is - a facet this steep can only be a cliff face, and the sea surface never gets that steep.
562
  float t = clamp(smoothstep(-0.12, 0.12, vEdge), 0.0, 1.0);
563
+ if(fn.y < 0.12) t = 1.0;
564
+ vec3 n = mix(wn, normalize(vNormal), t);
565
  if(n.y < 0.0) n = -n;
566
  vec3 col = mix(waterCol(wn), landCol(fn, max(vLand, 0.0)), t);
567
  float ndl = max(dot(n, LDIR), 0.0);