reze-engine 0.50.8 → 0.50.9

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.
@@ -19,6 +19,6 @@ export declare function commonFsOutWgsl(): string;
19
19
  * clumps of a few millimetres rather than as single-pixel snow, which at any
20
20
  * distance is just a fade.
21
21
  */
22
- export declare const DISSOLVE_WGSL = "\n/** Flake size, in object-space units \u2014 MMD's are roughly centimetres. */\nconst RZ_DISSOLVE_GRAIN: f32 = 0.55;\n/** How wide the glowing front is, in threshold units. */\nconst RZ_DISSOLVE_EDGE: f32 = 0.16;\n/** What the front burns with. Emission, added after lighting and after the\n * graph \u2014 a colour that ramps or takes a shadow reads as paint, not as heat.\n * Above 1 on purpose: it is meant to reach the bloom pyramid. */\nconst RZ_BURN_COLOR: vec3f = vec3f(0.55, 1.85, 2.60);\n\nfn rz_dissolve_hash(p: vec3f) -> f32 {\n let q = fract(p * 0.3183099 + vec3f(0.1, 0.2, 0.3));\n let r = q * 17.0 * (q + 34.0);\n return fract(r.x * r.y * r.z);\n}\n\n/** Value noise over that hash \u2014 smooth within a flake, uncorrelated between. */\nfn rz_dissolve_field(p: vec3f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let c000 = rz_dissolve_hash(i);\n let c100 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 0.0));\n let c010 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 0.0));\n let c110 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 0.0));\n let c001 = rz_dissolve_hash(i + vec3f(0.0, 0.0, 1.0));\n let c101 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 1.0));\n let c011 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 1.0));\n let c111 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 1.0));\n let x00 = mix(c000, c100, u.x);\n let x10 = mix(c010, c110, u.x);\n let x01 = mix(c001, c101, u.x);\n let x11 = mix(c011, c111, u.x);\n return mix(mix(x00, x10, u.y), mix(x01, x11, u.y), u.z);\n}\n\n/**\n * The threshold this fragment is measured against.\n *\n * Tilted by HEIGHT so the dissolve sweeps up the body instead of arriving\n * everywhere at once: a body that comes apart from the feet reads as something\n * happening TO her, and one that fades uniformly reads as an opacity slider.\n * The tilt is gentle \u2014 a third of the range \u2014 so the noise still decides which\n * flake goes when, and the sweep only decides roughly where it is.\n *\n * FEET FIRST, head last: the face is the last thing to go and the first thing\n * back, which is the order every disappearance in film is cut in. Object space\n * puts the floor at y = 0 on any PMX, so the tilt needs no rig measurement.\n */\nfn rz_dissolve_threshold(restPos: vec3f) -> f32 {\n let n = rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN);\n let low = 1.0 - clamp(restPos.y * 0.045, 0.0, 1.0);\n return clamp(n * 0.68 + low * 0.32, 0.0, 1.0);\n}\n";
22
+ export declare const DISSOLVE_WGSL = "\n/** Flake size, in object-space units \u2014 MMD's are roughly centimetres. */\nconst RZ_DISSOLVE_GRAIN: f32 = 0.55;\n/** How wide the glowing front is, in threshold units. */\nconst RZ_DISSOLVE_EDGE: f32 = 0.16;\n/** What the front burns with. Emission, added after lighting and after the\n * graph \u2014 a colour that ramps or takes a shadow reads as paint, not as heat.\n * Above 1 on purpose: it is meant to reach the bloom pyramid. */\nconst RZ_BURN_COLOR: vec3f = vec3f(0.55, 1.85, 2.60);\n\nfn rz_dissolve_hash(p: vec3f) -> f32 {\n let q = fract(p * 0.3183099 + vec3f(0.1, 0.2, 0.3));\n let r = q * 17.0 * (q + 34.0);\n return fract(r.x * r.y * r.z);\n}\n\n/** Value noise over that hash \u2014 smooth within a flake, uncorrelated between. */\nfn rz_dissolve_field(p: vec3f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let c000 = rz_dissolve_hash(i);\n let c100 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 0.0));\n let c010 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 0.0));\n let c110 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 0.0));\n let c001 = rz_dissolve_hash(i + vec3f(0.0, 0.0, 1.0));\n let c101 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 1.0));\n let c011 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 1.0));\n let c111 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 1.0));\n let x00 = mix(c000, c100, u.x);\n let x10 = mix(c010, c110, u.x);\n let x01 = mix(c001, c101, u.x);\n let x11 = mix(c011, c111, u.x);\n return mix(mix(x00, x10, u.y), mix(x01, x11, u.y), u.z);\n}\n\n/**\n * The threshold this fragment is measured against.\n *\n * NOISE ALONE, so the whole body comes apart at once \u2014 a hand, a shoulder and\n * an ankle all thinning together rather than a line travelling up her. It was\n * tilted by height at first, on the argument that a sweep reads as something\n * happening TO her; what it actually reads as is a wipe, and a wipe has a\n * direction, an edge and a speed the rest of the effect knows nothing about.\n * Everywhere at once is also the honest match for what leaves: the motes are\n * shed from every limb in the same breath.\n *\n * The value noise is what keeps it from being a fade. Flakes go in clumps a few\n * millimetres across, in an order that is fixed to the surface, so the same\n * piece of sleeve goes at the same moment every time she leaves.\n */\nfn rz_dissolve_threshold(restPos: vec3f) -> f32 {\n return clamp(rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN), 0.0, 1.0);\n}\n";
23
23
  export declare const COMMON_MATERIAL_PRELUDE_WGSL: string;
24
24
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/shaders/materials/common.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,oBAAoB,QAuHhC,CAAC;AAgIF,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa,q5EAsDzB,CAAA;AAQD,eAAO,MAAM,4BAA4B,QAC0D,CAAA"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/shaders/materials/common.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,oBAAoB,QAuHhC,CAAC;AAgIF,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa,+6EAsDzB,CAAA;AAQD,eAAO,MAAM,4BAA4B,QAC0D,CAAA"}
@@ -324,20 +324,20 @@ fn rz_dissolve_field(p: vec3f) -> f32 {
324
324
  /**
325
325
  * The threshold this fragment is measured against.
326
326
  *
327
- * Tilted by HEIGHT so the dissolve sweeps up the body instead of arriving
328
- * everywhere at once: a body that comes apart from the feet reads as something
329
- * happening TO her, and one that fades uniformly reads as an opacity slider.
330
- * The tilt is gentle a third of the range so the noise still decides which
331
- * flake goes when, and the sweep only decides roughly where it is.
327
+ * NOISE ALONE, so the whole body comes apart at once a hand, a shoulder and
328
+ * an ankle all thinning together rather than a line travelling up her. It was
329
+ * tilted by height at first, on the argument that a sweep reads as something
330
+ * happening TO her; what it actually reads as is a wipe, and a wipe has a
331
+ * direction, an edge and a speed the rest of the effect knows nothing about.
332
+ * Everywhere at once is also the honest match for what leaves: the motes are
333
+ * shed from every limb in the same breath.
332
334
  *
333
- * FEET FIRST, head last: the face is the last thing to go and the first thing
334
- * back, which is the order every disappearance in film is cut in. Object space
335
- * puts the floor at y = 0 on any PMX, so the tilt needs no rig measurement.
335
+ * The value noise is what keeps it from being a fade. Flakes go in clumps a few
336
+ * millimetres across, in an order that is fixed to the surface, so the same
337
+ * piece of sleeve goes at the same moment every time she leaves.
336
338
  */
337
339
  fn rz_dissolve_threshold(restPos: vec3f) -> f32 {
338
- let n = rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN);
339
- let low = 1.0 - clamp(restPos.y * 0.045, 0.0, 1.0);
340
- return clamp(n * 0.68 + low * 0.32, 0.0, 1.0);
340
+ return clamp(rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN), 0.0, 1.0);
341
341
  }
342
342
  `;
343
343
  // ─── Convenience: full shared prelude ───────────────────────────────
@@ -1,2 +1,2 @@
1
- export declare const SHADOW_DEPTH_SHADER_WGSL = "\n\n/** Flake size, in object-space units \u2014 MMD's are roughly centimetres. */\nconst RZ_DISSOLVE_GRAIN: f32 = 0.55;\n/** How wide the glowing front is, in threshold units. */\nconst RZ_DISSOLVE_EDGE: f32 = 0.16;\n/** What the front burns with. Emission, added after lighting and after the\n * graph \u2014 a colour that ramps or takes a shadow reads as paint, not as heat.\n * Above 1 on purpose: it is meant to reach the bloom pyramid. */\nconst RZ_BURN_COLOR: vec3f = vec3f(0.55, 1.85, 2.60);\n\nfn rz_dissolve_hash(p: vec3f) -> f32 {\n let q = fract(p * 0.3183099 + vec3f(0.1, 0.2, 0.3));\n let r = q * 17.0 * (q + 34.0);\n return fract(r.x * r.y * r.z);\n}\n\n/** Value noise over that hash \u2014 smooth within a flake, uncorrelated between. */\nfn rz_dissolve_field(p: vec3f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let c000 = rz_dissolve_hash(i);\n let c100 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 0.0));\n let c010 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 0.0));\n let c110 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 0.0));\n let c001 = rz_dissolve_hash(i + vec3f(0.0, 0.0, 1.0));\n let c101 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 1.0));\n let c011 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 1.0));\n let c111 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 1.0));\n let x00 = mix(c000, c100, u.x);\n let x10 = mix(c010, c110, u.x);\n let x01 = mix(c001, c101, u.x);\n let x11 = mix(c011, c111, u.x);\n return mix(mix(x00, x10, u.y), mix(x01, x11, u.y), u.z);\n}\n\n/**\n * The threshold this fragment is measured against.\n *\n * Tilted by HEIGHT so the dissolve sweeps up the body instead of arriving\n * everywhere at once: a body that comes apart from the feet reads as something\n * happening TO her, and one that fades uniformly reads as an opacity slider.\n * The tilt is gentle \u2014 a third of the range \u2014 so the noise still decides which\n * flake goes when, and the sweep only decides roughly where it is.\n *\n * FEET FIRST, head last: the face is the last thing to go and the first thing\n * back, which is the order every disappearance in film is cut in. Object space\n * puts the floor at y = 0 on any PMX, so the tilt needs no rig measurement.\n */\nfn rz_dissolve_threshold(restPos: vec3f) -> f32 {\n let n = rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN);\n let low = 1.0 - clamp(restPos.y * 0.045, 0.0, 1.0);\n return clamp(n * 0.68 + low * 0.32, 0.0, 1.0);\n}\n\nstruct LightVP { viewProj: mat4x4f, };\n@group(0) @binding(0) var<uniform> lp: LightVP;\n@group(0) @binding(1) var<storage, read> skinMats: array<mat4x4f>;\n@group(0) @binding(2) var texSampler: sampler;\n@group(1) @binding(0) var diffuseTexture: texture_2d<f32>;\n// The head of the material block and the one field at its tail \u2014 the same\n// reach the depth prepass takes, and for the same reason: a shadow cast by a\n// body that is no longer drawn is the tell that the vanishing is a trick.\nstruct MaterialDiffuse {\n diffuse: vec4f,\n _skip0: vec4f,\n _skip1: vec4f,\n _skip2: vec3f,\n dissolve: f32,\n};\n@group(1) @binding(1) var<uniform> material: MaterialDiffuse;\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n /** Bind-pose position, for the dissolve test \u2014 object space, as everywhere. */\n @location(1) restPos: vec3f,\n};\n\n@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f,\n @location(3) joints0: vec4<u32>, @location(4) weights0: vec4<f32>) -> VSOut {\n let pos4 = vec4f(position, 1.0);\n let ws = weights0.x + weights0.y + weights0.z + weights0.w;\n let inv = select(1.0, 1.0 / ws, ws > 0.0001);\n let nw = select(vec4f(1.0,0.0,0.0,0.0), weights0 * inv, ws > 0.0001);\n var sp = vec4f(0.0);\n for (var i = 0u; i < 4u; i++) { sp += (skinMats[joints0[i]] * pos4) * nw[i]; }\n var out: VSOut;\n out.position = lp.viewProj * vec4f(sp.xyz, 1.0);\n out.uv = uv;\n out.restPos = position;\n return out;\n}\n\n@fragment fn fs(in: VSOut) {\n let alpha = textureSample(diffuseTexture, texSampler, in.uv).a * material.diffuse.a;\n if (alpha < 0.5) { discard; }\n // The dissolve, run as the colour pass runs it. A flake that is gone stops\n // casting: without this she leaves a whole shadow standing on the floor while\n // her body is in the air.\n if (material.dissolve < 0.9995 && rz_dissolve_threshold(in.restPos) > material.dissolve) { discard; }\n}\n";
1
+ export declare const SHADOW_DEPTH_SHADER_WGSL = "\n\n/** Flake size, in object-space units \u2014 MMD's are roughly centimetres. */\nconst RZ_DISSOLVE_GRAIN: f32 = 0.55;\n/** How wide the glowing front is, in threshold units. */\nconst RZ_DISSOLVE_EDGE: f32 = 0.16;\n/** What the front burns with. Emission, added after lighting and after the\n * graph \u2014 a colour that ramps or takes a shadow reads as paint, not as heat.\n * Above 1 on purpose: it is meant to reach the bloom pyramid. */\nconst RZ_BURN_COLOR: vec3f = vec3f(0.55, 1.85, 2.60);\n\nfn rz_dissolve_hash(p: vec3f) -> f32 {\n let q = fract(p * 0.3183099 + vec3f(0.1, 0.2, 0.3));\n let r = q * 17.0 * (q + 34.0);\n return fract(r.x * r.y * r.z);\n}\n\n/** Value noise over that hash \u2014 smooth within a flake, uncorrelated between. */\nfn rz_dissolve_field(p: vec3f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let c000 = rz_dissolve_hash(i);\n let c100 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 0.0));\n let c010 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 0.0));\n let c110 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 0.0));\n let c001 = rz_dissolve_hash(i + vec3f(0.0, 0.0, 1.0));\n let c101 = rz_dissolve_hash(i + vec3f(1.0, 0.0, 1.0));\n let c011 = rz_dissolve_hash(i + vec3f(0.0, 1.0, 1.0));\n let c111 = rz_dissolve_hash(i + vec3f(1.0, 1.0, 1.0));\n let x00 = mix(c000, c100, u.x);\n let x10 = mix(c010, c110, u.x);\n let x01 = mix(c001, c101, u.x);\n let x11 = mix(c011, c111, u.x);\n return mix(mix(x00, x10, u.y), mix(x01, x11, u.y), u.z);\n}\n\n/**\n * The threshold this fragment is measured against.\n *\n * NOISE ALONE, so the whole body comes apart at once \u2014 a hand, a shoulder and\n * an ankle all thinning together rather than a line travelling up her. It was\n * tilted by height at first, on the argument that a sweep reads as something\n * happening TO her; what it actually reads as is a wipe, and a wipe has a\n * direction, an edge and a speed the rest of the effect knows nothing about.\n * Everywhere at once is also the honest match for what leaves: the motes are\n * shed from every limb in the same breath.\n *\n * The value noise is what keeps it from being a fade. Flakes go in clumps a few\n * millimetres across, in an order that is fixed to the surface, so the same\n * piece of sleeve goes at the same moment every time she leaves.\n */\nfn rz_dissolve_threshold(restPos: vec3f) -> f32 {\n return clamp(rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN), 0.0, 1.0);\n}\n\nstruct LightVP { viewProj: mat4x4f, };\n@group(0) @binding(0) var<uniform> lp: LightVP;\n@group(0) @binding(1) var<storage, read> skinMats: array<mat4x4f>;\n@group(0) @binding(2) var texSampler: sampler;\n@group(1) @binding(0) var diffuseTexture: texture_2d<f32>;\n// The head of the material block and the one field at its tail \u2014 the same\n// reach the depth prepass takes, and for the same reason: a shadow cast by a\n// body that is no longer drawn is the tell that the vanishing is a trick.\nstruct MaterialDiffuse {\n diffuse: vec4f,\n _skip0: vec4f,\n _skip1: vec4f,\n _skip2: vec3f,\n dissolve: f32,\n};\n@group(1) @binding(1) var<uniform> material: MaterialDiffuse;\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n /** Bind-pose position, for the dissolve test \u2014 object space, as everywhere. */\n @location(1) restPos: vec3f,\n};\n\n@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f,\n @location(3) joints0: vec4<u32>, @location(4) weights0: vec4<f32>) -> VSOut {\n let pos4 = vec4f(position, 1.0);\n let ws = weights0.x + weights0.y + weights0.z + weights0.w;\n let inv = select(1.0, 1.0 / ws, ws > 0.0001);\n let nw = select(vec4f(1.0,0.0,0.0,0.0), weights0 * inv, ws > 0.0001);\n var sp = vec4f(0.0);\n for (var i = 0u; i < 4u; i++) { sp += (skinMats[joints0[i]] * pos4) * nw[i]; }\n var out: VSOut;\n out.position = lp.viewProj * vec4f(sp.xyz, 1.0);\n out.uv = uv;\n out.restPos = position;\n return out;\n}\n\n@fragment fn fs(in: VSOut) {\n let alpha = textureSample(diffuseTexture, texSampler, in.uv).a * material.diffuse.a;\n if (alpha < 0.5) { discard; }\n // The dissolve, run as the colour pass runs it. A flake that is gone stops\n // casting: without this she leaves a whole shadow standing on the floor while\n // her body is in the air.\n if (material.dissolve < 0.9995 && rz_dissolve_threshold(in.restPos) > material.dissolve) { discard; }\n}\n";
2
2
  //# sourceMappingURL=shadow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/shadow.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,wBAAwB,y1IAiDpC,CAAA"}
1
+ {"version":3,"file":"shadow.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/shadow.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,wBAAwB,m3IAiDpC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.50.8",
3
+ "version": "0.50.9",
4
4
  "description": "A lightweight WebGPU engine for real-time 3D MMD/PMX model rendering",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -335,20 +335,20 @@ fn rz_dissolve_field(p: vec3f) -> f32 {
335
335
  /**
336
336
  * The threshold this fragment is measured against.
337
337
  *
338
- * Tilted by HEIGHT so the dissolve sweeps up the body instead of arriving
339
- * everywhere at once: a body that comes apart from the feet reads as something
340
- * happening TO her, and one that fades uniformly reads as an opacity slider.
341
- * The tilt is gentle a third of the range so the noise still decides which
342
- * flake goes when, and the sweep only decides roughly where it is.
338
+ * NOISE ALONE, so the whole body comes apart at once a hand, a shoulder and
339
+ * an ankle all thinning together rather than a line travelling up her. It was
340
+ * tilted by height at first, on the argument that a sweep reads as something
341
+ * happening TO her; what it actually reads as is a wipe, and a wipe has a
342
+ * direction, an edge and a speed the rest of the effect knows nothing about.
343
+ * Everywhere at once is also the honest match for what leaves: the motes are
344
+ * shed from every limb in the same breath.
343
345
  *
344
- * FEET FIRST, head last: the face is the last thing to go and the first thing
345
- * back, which is the order every disappearance in film is cut in. Object space
346
- * puts the floor at y = 0 on any PMX, so the tilt needs no rig measurement.
346
+ * The value noise is what keeps it from being a fade. Flakes go in clumps a few
347
+ * millimetres across, in an order that is fixed to the surface, so the same
348
+ * piece of sleeve goes at the same moment every time she leaves.
347
349
  */
348
350
  fn rz_dissolve_threshold(restPos: vec3f) -> f32 {
349
- let n = rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN);
350
- let low = 1.0 - clamp(restPos.y * 0.045, 0.0, 1.0);
351
- return clamp(n * 0.68 + low * 0.32, 0.0, 1.0);
351
+ return clamp(rz_dissolve_field(restPos / RZ_DISSOLVE_GRAIN), 0.0, 1.0);
352
352
  }
353
353
  `
354
354