ugly-game 0.5.11 → 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.
- package/dist/gpuShadow.d.ts +1 -1
- package/dist/gpuShadow.js +17 -6
- package/package.json +1 -1
package/dist/gpuShadow.d.ts
CHANGED
|
@@ -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;
|
|
@@ -260,14 +261,21 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
|
|
|
260
261
|
var variant = 1u; // side
|
|
261
262
|
if (d > 0.5) { variant = 0u; } else if (d < -0.5) { variant = 2u; }
|
|
262
263
|
let rect = tileRects[u32(i.tile) * 3u + variant];
|
|
263
|
-
|
|
264
|
+
// INSET the per-block UV so it never samples the tile's edge texels — otherwise linear filtering bleeds into
|
|
265
|
+
// the neighbouring atlas tile at every block boundary, drawing a hard seam GRID. 4% inset kills the seam.
|
|
266
|
+
let uv = rect.xy + (fract(vec2(fx, fz)) * 0.92 + 0.04) * rect.zw;
|
|
264
267
|
let texc = textureSampleLevel(atlasTex, atlasSamp, uv, 0.0).rgb; // explicit LOD (early-return above makes control flow non-uniform)
|
|
265
268
|
base = mix(texc, texc * cam.tint.rgb, cam.tint.w); // per-planet tint
|
|
266
269
|
}
|
|
267
270
|
// per-block edge AO makes each voxel visible on FLAT-hue cubes, but reads as a hard GRID over textures — so the
|
|
268
|
-
// atlas path
|
|
269
|
-
let ao = select(blockShade(fx, fz),
|
|
270
|
-
|
|
271
|
+
// atlas path drops it entirely (the texture already supplies surface detail).
|
|
272
|
+
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;
|
|
271
279
|
return vec4(pow(clamp(lit, vec3(0.0), vec3(1.0)), vec3(0.4545)), 1.0); // gamma
|
|
272
280
|
}
|
|
273
281
|
`;
|
|
@@ -302,7 +310,7 @@ export class GpuShadowRenderer {
|
|
|
302
310
|
mainBGL;
|
|
303
311
|
shadowSampler;
|
|
304
312
|
count = 0;
|
|
305
|
-
cam = new Float32Array(
|
|
313
|
+
cam = new Float32Array(52); // 2×mat4 + sun + sunCol + tint + atlas + up
|
|
306
314
|
atlasView;
|
|
307
315
|
atlasSampler;
|
|
308
316
|
tileRectBuf;
|
|
@@ -583,7 +591,7 @@ export class GpuShadowRenderer {
|
|
|
583
591
|
/** camVP/lightVP: column-major Float32Array(16). sunDir: travel direction. Pass `occlusion` (the depth target +
|
|
584
592
|
* its size) to enable Hi-Z occlusion culling on the camera pass — the renderer rebuilds a coarse Hi-Z from that
|
|
585
593
|
* depth each frame and the NEXT frame's cull uses it (hole-free: the first frame + any resize skip occlusion). */
|
|
586
|
-
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]) {
|
|
587
595
|
this.cam.set(camVP, 0);
|
|
588
596
|
this.cam.set(lightVP, 16);
|
|
589
597
|
this.cam[32] = sunDir[0];
|
|
@@ -599,6 +607,9 @@ export class GpuShadowRenderer {
|
|
|
599
607
|
this.cam[42] = tint[2];
|
|
600
608
|
this.cam[43] = tint[3];
|
|
601
609
|
this.cam[44] = this.useAtlas;
|
|
610
|
+
this.cam[48] = up[0];
|
|
611
|
+
this.cam[49] = up[1];
|
|
612
|
+
this.cam[50] = up[2];
|
|
602
613
|
this.device.queue.writeBuffer(this.camBuf, 0, this.cam);
|
|
603
614
|
if (occlusion)
|
|
604
615
|
this.ensureHiZ(occlusion.w, occlusion.h);
|