reze-engine 0.54.0 → 0.54.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/outline.ts"],"names":[],"mappings":"AAoBA,wBAAgB,iBAAiB,IAAI,MAAM,CAqG1C"}
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/outline.ts"],"names":[],"mappings":"AAqBA,wBAAgB,iBAAiB,IAAI,MAAM,CA+H1C"}
@@ -15,8 +15,10 @@
15
15
  // fragment outputs depend on whether the device carries the id attachment, and
16
16
  // a string baked at import cannot know what the device said.
17
17
  import { sceneFsOutWgsl, sceneIdPadWgsl } from "./scene-contract";
18
+ import { DISSOLVE_WGSL } from "../materials/common";
18
19
  export function outlineShaderWgsl() {
19
20
  return /* wgsl */ `
21
+ ${DISSOLVE_WGSL}
20
22
  struct CameraUniforms {
21
23
  view: mat4x4f,
22
24
  projection: mat4x4f,
@@ -26,12 +28,20 @@ struct CameraUniforms {
26
28
  viewportHeight: f32,
27
29
  };
28
30
 
31
+ // The head of the material block, plus the one field at its tail. The middle is
32
+ // skipped rather than named: this pass shades nothing, and every field it
33
+ // declared would be a field that has to stay in step with the real struct for
34
+ // no gain. The padding is explicit so the offsets are checkable by eye —
35
+ // edgeColor at 0, edgeSize at 16, and dissolve last at 60.
29
36
  struct MaterialUniforms {
30
37
  edgeColor: vec4f,
31
38
  edgeSize: f32,
32
39
  _padding1: f32,
33
40
  _padding2: f32,
34
41
  _padding3: f32,
42
+ _skip0: vec4f,
43
+ _skip1: vec3f,
44
+ dissolve: f32,
35
45
  };
36
46
 
37
47
  @group(0) @binding(0) var<uniform> camera: CameraUniforms;
@@ -43,6 +53,10 @@ struct MaterialUniforms {
43
53
  struct VertexOutput {
44
54
  @builtin(position) position: vec4f,
45
55
  @location(0) uv: vec2f,
56
+ /** BIND-POSE position, for the dissolve — the same value the colour pass and
57
+ * the depth prepass measure against, so all three agree about which flakes
58
+ * are gone. */
59
+ @location(1) restPos: vec3f,
46
60
  };
47
61
 
48
62
  @vertex fn vs(
@@ -92,6 +106,7 @@ struct VertexOutput {
92
106
  let offset = screenNormal * (material.edgeSize * 4.0 / viewport) * clipPos.w;
93
107
  output.position = vec4f(clipPos.xy + offset, clipPos.z, clipPos.w);
94
108
  output.uv = uv;
109
+ output.restPos = position;
95
110
  return output;
96
111
  }
97
112
 
@@ -106,6 +121,18 @@ ${sceneFsOutWgsl({ name: "FSOut", aux: "mask" })}
106
121
  // legs crossing lost their outline entirely. Modulating instead keeps a
107
122
  // proportional rim on sheer weave (never a solid black hull) and still
108
123
  // discards true cut-out margins like hair-card borders.
124
+ // THE HULL GOES WITH THE SURFACE IT TRACES.
125
+ //
126
+ // Without this the outline pass was the one pass that ignored the dissolve:
127
+ // the body discarded flake by flake and its hulls stayed, so a character who
128
+ // had gone left a solid silhouette in her own edge colour standing where she
129
+ // had been. Only models whose materials carry MMD's edge flag showed it,
130
+ // which is what made it look like some models "would not dissolve".
131
+ //
132
+ // The same test the colour pass and the depth prepass run, against the same
133
+ // bind-pose position — three passes, one rule, or they disagree about which
134
+ // pieces are still there.
135
+ if (material.dissolve < 0.9995 && rz_dissolve_threshold(input.restPos) > material.dissolve) { discard; }
109
136
  let texA = textureSample(diffuseTexture, edgeSampler, input.uv).a;
110
137
  if (texA < 0.05) {
111
138
  discard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.54.0",
3
+ "version": "0.54.1",
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",
@@ -17,9 +17,11 @@
17
17
  // a string baked at import cannot know what the device said.
18
18
 
19
19
  import { sceneFsOutWgsl, sceneIdPadWgsl } from "./scene-contract"
20
+ import { DISSOLVE_WGSL } from "../materials/common"
20
21
 
21
22
  export function outlineShaderWgsl(): string {
22
23
  return /* wgsl */ `
24
+ ${DISSOLVE_WGSL}
23
25
  struct CameraUniforms {
24
26
  view: mat4x4f,
25
27
  projection: mat4x4f,
@@ -29,12 +31,20 @@ struct CameraUniforms {
29
31
  viewportHeight: f32,
30
32
  };
31
33
 
34
+ // The head of the material block, plus the one field at its tail. The middle is
35
+ // skipped rather than named: this pass shades nothing, and every field it
36
+ // declared would be a field that has to stay in step with the real struct for
37
+ // no gain. The padding is explicit so the offsets are checkable by eye —
38
+ // edgeColor at 0, edgeSize at 16, and dissolve last at 60.
32
39
  struct MaterialUniforms {
33
40
  edgeColor: vec4f,
34
41
  edgeSize: f32,
35
42
  _padding1: f32,
36
43
  _padding2: f32,
37
44
  _padding3: f32,
45
+ _skip0: vec4f,
46
+ _skip1: vec3f,
47
+ dissolve: f32,
38
48
  };
39
49
 
40
50
  @group(0) @binding(0) var<uniform> camera: CameraUniforms;
@@ -46,6 +56,10 @@ struct MaterialUniforms {
46
56
  struct VertexOutput {
47
57
  @builtin(position) position: vec4f,
48
58
  @location(0) uv: vec2f,
59
+ /** BIND-POSE position, for the dissolve — the same value the colour pass and
60
+ * the depth prepass measure against, so all three agree about which flakes
61
+ * are gone. */
62
+ @location(1) restPos: vec3f,
49
63
  };
50
64
 
51
65
  @vertex fn vs(
@@ -95,6 +109,7 @@ struct VertexOutput {
95
109
  let offset = screenNormal * (material.edgeSize * 4.0 / viewport) * clipPos.w;
96
110
  output.position = vec4f(clipPos.xy + offset, clipPos.z, clipPos.w);
97
111
  output.uv = uv;
112
+ output.restPos = position;
98
113
  return output;
99
114
  }
100
115
 
@@ -109,6 +124,18 @@ ${sceneFsOutWgsl({ name: "FSOut", aux: "mask" })}
109
124
  // legs crossing lost their outline entirely. Modulating instead keeps a
110
125
  // proportional rim on sheer weave (never a solid black hull) and still
111
126
  // discards true cut-out margins like hair-card borders.
127
+ // THE HULL GOES WITH THE SURFACE IT TRACES.
128
+ //
129
+ // Without this the outline pass was the one pass that ignored the dissolve:
130
+ // the body discarded flake by flake and its hulls stayed, so a character who
131
+ // had gone left a solid silhouette in her own edge colour standing where she
132
+ // had been. Only models whose materials carry MMD's edge flag showed it,
133
+ // which is what made it look like some models "would not dissolve".
134
+ //
135
+ // The same test the colour pass and the depth prepass run, against the same
136
+ // bind-pose position — three passes, one rule, or they disagree about which
137
+ // pieces are still there.
138
+ if (material.dissolve < 0.9995 && rz_dissolve_threshold(input.restPos) > material.dissolve) { discard; }
112
139
  let texA = textureSample(diffuseTexture, edgeSampler, input.uv).a;
113
140
  if (texA < 0.05) {
114
141
  discard;