reze-engine 0.68.7 → 0.68.8

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":"AAqBA;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAC5C;yCACyC;AACzC,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;mEACmE;AACnE,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;;yCAEyC;AACzC,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAC5C,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAC1C,uCAAuC;AACvC,eAAO,MAAM,yBAAyB,KAAK,CAAA;AAE3C,wBAAgB,iBAAiB,IAAI,MAAM,CAgP1C"}
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/outline.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAC5C;yCACyC;AACzC,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;mEACmE;AACnE,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;;yCAEyC;AACzC,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAC5C,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAC1C,uCAAuC;AACvC,eAAO,MAAM,yBAAyB,KAAK,CAAA;AAE3C,wBAAgB,iBAAiB,IAAI,MAAM,CA2P1C"}
@@ -193,12 +193,22 @@ fn safe_normal2(v: vec2f) -> vec2f {
193
193
  let w = max(clipPos.w, 1e-4);
194
194
  var ndc: vec2f;
195
195
  var coverage = 1.0;
196
+ // The scene's width dial splits around 1×. Above it, it widens the line
197
+ // before the minimum, as it always has. Below it, it thins the line AFTER
198
+ // the minimum: a line held at the minimum is drawn that wide and faded, and
199
+ // it still writes depth across all of it — so a dial at 0.1× or at 0.0001×
200
+ // left the same 1.5 px ring for whatever drew or read depth after it, and
201
+ // the dial did nothing visible. Thinned past the minimum instead, the hull
202
+ // is genuinely sub-pixel, the multisampling covers only what it covers, and
203
+ // the line fades with the dial and claims depth only where it is.
204
+ let widen = max(material.widthScale, 1.0);
205
+ let thin = min(material.widthScale, 1.0);
196
206
  if (material.textured > 0.5) {
197
207
  // The game's: a view-space offset of edgeSize world units along the view
198
208
  // normal, projected, then each axis held between 1.2 px and 1.2 px ×
199
209
  // (1 + _OutlineMaxOffsetMultiplier, 1.5) of a 1920-wide frame; a line the
200
210
  // minimum had to push fades by how far it was pushed.
201
- let off = viewNormal.xy * material.edgeSize * material.widthScale * outlineNormal.w;
211
+ let off = viewNormal.xy * material.edgeSize * widen * outlineNormal.w;
202
212
  let d1 = vec2f(off.x * camera.projection[0][0], off.y * camera.projection[1][1]) / w;
203
213
  // the minimum along the push direction (the game's dir · 2/screen · 1.2)
204
214
  let pxNdc = 2.0 / refViewport * 1.2 * safe_normal2(viewNormal.xy);
@@ -210,7 +220,7 @@ fn safe_normal2(v: vec2f) -> vec2f {
210
220
  ndc = o * select(vec2f(1.0), sign(d1), abs(d1) > vec2f(0.0));
211
221
  } else {
212
222
  let breakDepth = RZ_OUTLINE_FULL_FIGURE * camera.projection[1][1];
213
- let nearNdc = viewNormal.xy * (material.edgeSize * material.widthScale * outlineNormal.w * 4.0 / refViewport);
223
+ let nearNdc = viewNormal.xy * (material.edgeSize * widen * outlineNormal.w * 4.0 / refViewport);
214
224
  ndc = nearNdc * (min(w, breakDepth) / w);
215
225
 
216
226
  // Antialiased minimum (the game's _OutlineAntialias): held at the minimum
@@ -224,6 +234,7 @@ fn safe_normal2(v: vec2f) -> vec2f {
224
234
  ndc = select(vec2f(0.0), ndc * (minPx / px), px > 1e-6);
225
235
  }
226
236
  }
237
+ ndc *= thin;
227
238
  output.normal = worldNormal;
228
239
  output.coverage = coverage;
229
240
  output.position = vec4f(clipPos.xy + ndc * w, clipPos.z, clipPos.w);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.68.7",
3
+ "version": "0.68.8",
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",
@@ -197,12 +197,22 @@ fn safe_normal2(v: vec2f) -> vec2f {
197
197
  let w = max(clipPos.w, 1e-4);
198
198
  var ndc: vec2f;
199
199
  var coverage = 1.0;
200
+ // The scene's width dial splits around 1×. Above it, it widens the line
201
+ // before the minimum, as it always has. Below it, it thins the line AFTER
202
+ // the minimum: a line held at the minimum is drawn that wide and faded, and
203
+ // it still writes depth across all of it — so a dial at 0.1× or at 0.0001×
204
+ // left the same 1.5 px ring for whatever drew or read depth after it, and
205
+ // the dial did nothing visible. Thinned past the minimum instead, the hull
206
+ // is genuinely sub-pixel, the multisampling covers only what it covers, and
207
+ // the line fades with the dial and claims depth only where it is.
208
+ let widen = max(material.widthScale, 1.0);
209
+ let thin = min(material.widthScale, 1.0);
200
210
  if (material.textured > 0.5) {
201
211
  // The game's: a view-space offset of edgeSize world units along the view
202
212
  // normal, projected, then each axis held between 1.2 px and 1.2 px ×
203
213
  // (1 + _OutlineMaxOffsetMultiplier, 1.5) of a 1920-wide frame; a line the
204
214
  // minimum had to push fades by how far it was pushed.
205
- let off = viewNormal.xy * material.edgeSize * material.widthScale * outlineNormal.w;
215
+ let off = viewNormal.xy * material.edgeSize * widen * outlineNormal.w;
206
216
  let d1 = vec2f(off.x * camera.projection[0][0], off.y * camera.projection[1][1]) / w;
207
217
  // the minimum along the push direction (the game's dir · 2/screen · 1.2)
208
218
  let pxNdc = 2.0 / refViewport * 1.2 * safe_normal2(viewNormal.xy);
@@ -214,7 +224,7 @@ fn safe_normal2(v: vec2f) -> vec2f {
214
224
  ndc = o * select(vec2f(1.0), sign(d1), abs(d1) > vec2f(0.0));
215
225
  } else {
216
226
  let breakDepth = RZ_OUTLINE_FULL_FIGURE * camera.projection[1][1];
217
- let nearNdc = viewNormal.xy * (material.edgeSize * material.widthScale * outlineNormal.w * 4.0 / refViewport);
227
+ let nearNdc = viewNormal.xy * (material.edgeSize * widen * outlineNormal.w * 4.0 / refViewport);
218
228
  ndc = nearNdc * (min(w, breakDepth) / w);
219
229
 
220
230
  // Antialiased minimum (the game's _OutlineAntialias): held at the minimum
@@ -228,6 +238,7 @@ fn safe_normal2(v: vec2f) -> vec2f {
228
238
  ndc = select(vec2f(0.0), ndc * (minPx / px), px > 1e-6);
229
239
  }
230
240
  }
241
+ ndc *= thin;
231
242
  output.normal = worldNormal;
232
243
  output.coverage = coverage;
233
244
  output.position = vec4f(clipPos.xy + ndc * w, clipPos.z, clipPos.w);