ugly-game 0.5.12 → 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.
- package/dist/gpuShadow.d.ts +1 -1
- package/dist/gpuShadow.js +25 -3
- 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;
|
|
@@ -239,6 +240,18 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
|
|
|
239
240
|
let t = clamp(edge / 0.17, 0.0, 1.0);
|
|
240
241
|
return 0.6 + 0.4 * (t * t * (3.0 - 2.0 * t));
|
|
241
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
|
+
}
|
|
242
255
|
@fragment fn fs(i: VOut) -> @location(0) vec4<f32> {
|
|
243
256
|
if (i.emis > 0.5) { // self-glowing effect cube: full-bright, unlit
|
|
244
257
|
let g = mix(hsv(i.hue), vec3(1.0), 0.4);
|
|
@@ -269,7 +282,13 @@ fn blockShade(fx: f32, fz: f32) -> f32 {
|
|
|
269
282
|
// per-block edge AO makes each voxel visible on FLAT-hue cubes, but reads as a hard GRID over textures — so the
|
|
270
283
|
// atlas path drops it entirely (the texture already supplies surface detail).
|
|
271
284
|
let ao = select(blockShade(fx, fz), 1.0, cam.atlas.x > 0.5 && i.tile >= 0.0);
|
|
272
|
-
|
|
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
|
|
273
292
|
return vec4(pow(clamp(lit, vec3(0.0), vec3(1.0)), vec3(0.4545)), 1.0); // gamma
|
|
274
293
|
}
|
|
275
294
|
`;
|
|
@@ -304,7 +323,7 @@ export class GpuShadowRenderer {
|
|
|
304
323
|
mainBGL;
|
|
305
324
|
shadowSampler;
|
|
306
325
|
count = 0;
|
|
307
|
-
cam = new Float32Array(
|
|
326
|
+
cam = new Float32Array(52); // 2×mat4 + sun + sunCol + tint + atlas + up
|
|
308
327
|
atlasView;
|
|
309
328
|
atlasSampler;
|
|
310
329
|
tileRectBuf;
|
|
@@ -585,7 +604,7 @@ export class GpuShadowRenderer {
|
|
|
585
604
|
/** camVP/lightVP: column-major Float32Array(16). sunDir: travel direction. Pass `occlusion` (the depth target +
|
|
586
605
|
* its size) to enable Hi-Z occlusion culling on the camera pass — the renderer rebuilds a coarse Hi-Z from that
|
|
587
606
|
* 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) {
|
|
607
|
+
frame(enc, colorView, sceneDepth, camVP, lightVP, sunDir, sunCol, ambient, load = false, occlusion, tint = [1, 1, 1, 0], extraShadow, up = [0, 1, 0]) {
|
|
589
608
|
this.cam.set(camVP, 0);
|
|
590
609
|
this.cam.set(lightVP, 16);
|
|
591
610
|
this.cam[32] = sunDir[0];
|
|
@@ -601,6 +620,9 @@ export class GpuShadowRenderer {
|
|
|
601
620
|
this.cam[42] = tint[2];
|
|
602
621
|
this.cam[43] = tint[3];
|
|
603
622
|
this.cam[44] = this.useAtlas;
|
|
623
|
+
this.cam[48] = up[0];
|
|
624
|
+
this.cam[49] = up[1];
|
|
625
|
+
this.cam[50] = up[2];
|
|
604
626
|
this.device.queue.writeBuffer(this.camBuf, 0, this.cam);
|
|
605
627
|
if (occlusion)
|
|
606
628
|
this.ensureHiZ(occlusion.w, occlusion.h);
|