ugly-game 0.5.12 → 0.5.13

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.
@@ -107,7 +107,7 @@ export declare class GpuShadowRenderer {
107
107
  depth: GPUTextureView;
108
108
  w: number;
109
109
  h: number;
110
- }, tint?: [number, number, number, number], extraShadow?: (sp: GPURenderPassEncoder, lightVP: Float32Array) => void): void;
110
+ }, tint?: [number, number, number, number], extraShadow?: (sp: GPURenderPassEncoder, lightVP: Float32Array) => void, up?: [number, number, number]): void;
111
111
  /** Read back the last frame's GPU cull result (camera-visible, light-visible). Does its OWN copy+submit so it's
112
112
  * safe to call from a live render loop (no per-frame readback cost, no race with the ongoing frames). IR/tests. */
113
113
  readCullStats(): Promise<{
package/dist/gpuShadow.js CHANGED
@@ -51,6 +51,7 @@ struct Cam {
51
51
  sunCol: vec4<f32>, // xyz = sun colour, w = shadow map size (texels)
52
52
  tint: vec4<f32>, // rgb = per-planet tint · w = tint strength (0 = none)
53
53
  atlas: vec4<f32>, // x = useAtlas (1/0)
54
+ up: vec4<f32>, // xyz = local gravity up (for hemisphere face-shading readability); w unused
54
55
  };
55
56
  struct Inst { pos: vec4<f32>, scl: vec4<f32>, rot: vec4<f32>, aux: vec4<f32> }; // pos.w = hue (<0 ⇒ ground) · scl.w = emissive/alpha · rot = quaternion · aux.x = atlas tile (<0 ⇒ hue) · aux.y = up-face code
56
57
  @group(0) @binding(0) var<uniform> cam: Cam;
@@ -269,7 +270,12 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
269
270
  // per-block edge AO makes each voxel visible on FLAT-hue cubes, but reads as a hard GRID over textures — so the
270
271
  // atlas path drops it entirely (the texture already supplies surface detail).
271
272
  let ao = select(blockShade(fx, fz), 1.0, cam.atlas.x > 0.5 && i.tile >= 0.0);
272
- let lit = base * (cam.sun.w + cam.sunCol.xyz * ndl * sh) * ao;
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;
273
279
  return vec4(pow(clamp(lit, vec3(0.0), vec3(1.0)), vec3(0.4545)), 1.0); // gamma
274
280
  }
275
281
  `;
@@ -304,7 +310,7 @@ export class GpuShadowRenderer {
304
310
  mainBGL;
305
311
  shadowSampler;
306
312
  count = 0;
307
- cam = new Float32Array(48); // 2×mat4 + sun + sunCol + tint + atlas
313
+ cam = new Float32Array(52); // 2×mat4 + sun + sunCol + tint + atlas + up
308
314
  atlasView;
309
315
  atlasSampler;
310
316
  tileRectBuf;
@@ -585,7 +591,7 @@ export class GpuShadowRenderer {
585
591
  /** camVP/lightVP: column-major Float32Array(16). sunDir: travel direction. Pass `occlusion` (the depth target +
586
592
  * its size) to enable Hi-Z occlusion culling on the camera pass — the renderer rebuilds a coarse Hi-Z from that
587
593
  * depth each frame and the NEXT frame's cull uses it (hole-free: the first frame + any resize skip occlusion). */
588
- frame(enc, colorView, sceneDepth, camVP, lightVP, sunDir, sunCol, ambient, load = false, occlusion, tint = [1, 1, 1, 0], extraShadow) {
594
+ frame(enc, colorView, sceneDepth, camVP, lightVP, sunDir, sunCol, ambient, load = false, occlusion, tint = [1, 1, 1, 0], extraShadow, up = [0, 1, 0]) {
589
595
  this.cam.set(camVP, 0);
590
596
  this.cam.set(lightVP, 16);
591
597
  this.cam[32] = sunDir[0];
@@ -601,6 +607,9 @@ export class GpuShadowRenderer {
601
607
  this.cam[42] = tint[2];
602
608
  this.cam[43] = tint[3];
603
609
  this.cam[44] = this.useAtlas;
610
+ this.cam[48] = up[0];
611
+ this.cam[49] = up[1];
612
+ this.cam[50] = up[2];
604
613
  this.device.queue.writeBuffer(this.camBuf, 0, this.cam);
605
614
  if (occlusion)
606
615
  this.ensureHiZ(occlusion.w, occlusion.h);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-game",
3
- "version": "0.5.12",
3
+ "version": "0.5.13",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {