ugly-game 0.5.13 → 0.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/gpuShadow.js +19 -6
  2. package/package.json +1 -1
package/dist/gpuShadow.js CHANGED
@@ -240,6 +240,18 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
240
240
  let t = clamp(edge / 0.17, 0.0, 1.0);
241
241
  return 0.6 + 0.4 * (t * t * (3.0 - 2.0 * t));
242
242
  }
243
+ // Minecraft-style FIXED per-face directional shade (independent of the sun) — the reliable readability cue for
244
+ // voxel terrain: top brightest, bottom darkest, and the TWO horizontal axes get DISTINCT brightness so any cube's
245
+ // three visible faces all differ - corners, steps and terrace risers read at a glance at ANY sun angle. up is
246
+ // the local gravity up; t is a stable horizontal tangent used only to break the side-face symmetry.
247
+ fn faceDirShade(N: vec3<f32>, up: vec3<f32>) -> f32 {
248
+ var t = cross(up, vec3(0.0, 0.0, 1.0));
249
+ if (dot(t, t) < 0.01) { t = cross(up, vec3(1.0, 0.0, 0.0)); }
250
+ t = normalize(t);
251
+ let nu = dot(N, up); // +1 up-facing, 0 side, -1 down-facing
252
+ let nt = dot(N, t); // splits the two horizontal side-axes apart
253
+ return clamp(0.68 + 0.32 * nu + 0.14 * nt, 0.36, 1.0);
254
+ }
243
255
  @fragment fn fs(i: VOut) -> @location(0) vec4<f32> {
244
256
  if (i.emis > 0.5) { // self-glowing effect cube: full-bright, unlit
245
257
  let g = mix(hsv(i.hue), vec3(1.0), 0.4);
@@ -270,12 +282,13 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
270
282
  // per-block edge AO makes each voxel visible on FLAT-hue cubes, but reads as a hard GRID over textures — so the
271
283
  // atlas path drops it entirely (the texture already supplies surface detail).
272
284
  let ao = select(blockShade(fx, fz), 1.0, cam.atlas.x > 0.5 && i.tile >= 0.0);
273
- // HEMISPHERE FACE-SHADING: brighten faces pointing toward the local up (sky), darken side/down faces so every
274
- // block's orientation reads at a glance (edges/corners legible) WITHOUT a per-block grid. Modulates the ambient
275
- // sky term (not the direct sun), so sunlit faces keep full key light while shaded areas still show 3D form.
276
- let hemi = dot(N, cam.up.xyz) * 0.5 + 0.5; // 0 = down-facing, 0.5 = side, 1 = up-facing
277
- let amb = cam.sun.w * mix(0.55, 1.15, hemi);
278
- let lit = base * (amb + cam.sunCol.xyz * ndl * sh) * ao;
285
+ // FACE-DIRECTIONAL SHADING (Minecraft-style, sun-independent) makes the 3D shape read at any time of day. It
286
+ // tints the ambient FILL heavily AND is applied at partial strength to the whole lit result so even a face in
287
+ // full key light still shows its orientation, and terrace risers stay clearly darker than the tops above them.
288
+ let dir = faceDirShade(N, cam.up.xyz);
289
+ let fill = cam.sun.w * mix(0.5, 1.25, dir); // ambient sky term, strongly tinted by face orientation
290
+ let key = cam.sunCol.xyz * ndl * sh; // direct sun (shadowed)
291
+ let lit = base * (fill + key) * ao * (0.72 + 0.28 * dir); // 0.72..1.0 fixed face-light keeps corners legible under full sun
279
292
  return vec4(pow(clamp(lit, vec3(0.0), vec3(1.0)), vec3(0.4545)), 1.0); // gamma
280
293
  }
281
294
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-game",
3
- "version": "0.5.13",
3
+ "version": "0.5.14",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {