reze-engine 0.57.3 → 0.57.4

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":"trails.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/trails.ts"],"names":[],"mappings":"AA4BA,KAAK,WAAW,GAAG;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb;oEACgE;IAChE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,GAAG,UAAU,CAAA;IAC3B,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAKjF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE;IACJ,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,CAAA;IACf;;;;kFAI8E;IAC9E,SAAS,EAAE,OAAO,CAAA;CACnB,GACA,MAAM,CA6WR"}
1
+ {"version":3,"file":"trails.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/trails.ts"],"names":[],"mappings":"AA4BA,KAAK,WAAW,GAAG;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb;oEACgE;IAChE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,GAAG,UAAU,CAAA;IAC3B,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAKjF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE;IACJ,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,CAAA;IACf;;;;kFAI8E;IAC9E,SAAS,EAAE,OAAO,CAAA;CACnB,GACA,MAAM,CAyZR"}
@@ -128,18 +128,62 @@ fn _rzCastLive() -> i32 {
128
128
  }
129
129
  return n;
130
130
  }
131
+ /**
132
+ * CENTRIPETAL knot spacing: the square root of the chord.
133
+ *
134
+ * The whole reason the spline below is not the textbook one-liner. Uniform
135
+ * Catmull-Rom takes the tangent at p1 to be (p2 - p0)/2 — a quantity that knows
136
+ * nothing about how far apart those samples actually are. Trails are sampled at
137
+ * a FIXED RATE, so a hand that accelerates leaves one segment far longer than
138
+ * its neighbours, and a tangent sized for the long one applied over the short
139
+ * one swings the curve far outside the control polygon: the ribbon bulges out
140
+ * to a place no sample ever was, which reads as the trail teleporting, and it
141
+ * happens precisely on the quick moves.
142
+ *
143
+ * Spacing the knots by sqrt(chord) — alpha = 0.5, the centripetal variant — is
144
+ * the standard cure, and it is the only alpha proven to produce no cusp and no
145
+ * self-intersection whatever the samples do.
146
+ */
147
+ fn rzKnot(a: vec3f, b: vec3f) -> f32 {
148
+ return max(sqrt(distance(a, b)), 1e-4);
149
+ }
150
+
151
+ /** The two Hermite tangents of the segment p1..p2, sized by real chord lengths. */
152
+ fn rzSplineTangents(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f) -> mat2x3f {
153
+ let d0 = rzKnot(p0, p1);
154
+ let d1 = rzKnot(p1, p2);
155
+ let d2 = rzKnot(p2, p3);
156
+ let m1 = ((p1 - p0) / d0 - (p2 - p0) / (d0 + d1) + (p2 - p1) / d1) * d1;
157
+ let m2 = ((p2 - p1) / d1 - (p3 - p1) / (d1 + d2) + (p3 - p2) / d2) * d1;
158
+ return mat2x3f(m1, m2);
159
+ }
160
+
131
161
  /** Catmull-Rom through four samples — passes through p1 and p2. */
132
162
  fn rzSpline(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f, t: f32) -> vec3f {
163
+ let m = rzSplineTangents(p0, p1, p2, p3);
133
164
  let t2 = t * t;
134
165
  let t3 = t2 * t;
135
- return 0.5 * ((2.0 * p1) + (-p0 + p2) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
136
- (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
166
+ return (2.0 * t3 - 3.0 * t2 + 1.0) * p1
167
+ + (t3 - 2.0 * t2 + t) * m[0]
168
+ + (-2.0 * t3 + 3.0 * t2) * p2
169
+ + (t3 - t2) * m[1];
137
170
  }
138
- /** Its derivative — the ribbon's direction, smooth by construction. */
171
+
172
+ /**
173
+ * Its derivative — the ribbon's direction, smooth by construction.
174
+ *
175
+ * Still exact at the knots, which is what the shared edge depends on: at t = 1
176
+ * this is m2 and at t = 0 it is m1, and the two segments meeting at a sample
177
+ * derive those from the same three points. They differ only by a positive
178
+ * scale, and this normalises, so both quads get the identical direction.
179
+ */
139
180
  fn rzSplineTangent(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f, t: f32) -> vec3f {
181
+ let m = rzSplineTangents(p0, p1, p2, p3);
140
182
  let t2 = t * t;
141
- let d = 0.5 * ((-p0 + p2) + 2.0 * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t +
142
- 3.0 * (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t2);
183
+ let d = (6.0 * t2 - 6.0 * t) * p1
184
+ + (3.0 * t2 - 4.0 * t + 1.0) * m[0]
185
+ + (-6.0 * t2 + 6.0 * t) * p2
186
+ + (3.0 * t2 - 2.0 * t) * m[1];
143
187
  if (length(d) < 1e-6) { return vec3f(0.0, 1.0, 0.0); }
144
188
  return normalize(d);
145
189
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.57.3",
3
+ "version": "0.57.4",
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",
@@ -179,18 +179,62 @@ fn _rzCastLive() -> i32 {
179
179
  }
180
180
  return n;
181
181
  }
182
+ /**
183
+ * CENTRIPETAL knot spacing: the square root of the chord.
184
+ *
185
+ * The whole reason the spline below is not the textbook one-liner. Uniform
186
+ * Catmull-Rom takes the tangent at p1 to be (p2 - p0)/2 — a quantity that knows
187
+ * nothing about how far apart those samples actually are. Trails are sampled at
188
+ * a FIXED RATE, so a hand that accelerates leaves one segment far longer than
189
+ * its neighbours, and a tangent sized for the long one applied over the short
190
+ * one swings the curve far outside the control polygon: the ribbon bulges out
191
+ * to a place no sample ever was, which reads as the trail teleporting, and it
192
+ * happens precisely on the quick moves.
193
+ *
194
+ * Spacing the knots by sqrt(chord) — alpha = 0.5, the centripetal variant — is
195
+ * the standard cure, and it is the only alpha proven to produce no cusp and no
196
+ * self-intersection whatever the samples do.
197
+ */
198
+ fn rzKnot(a: vec3f, b: vec3f) -> f32 {
199
+ return max(sqrt(distance(a, b)), 1e-4);
200
+ }
201
+
202
+ /** The two Hermite tangents of the segment p1..p2, sized by real chord lengths. */
203
+ fn rzSplineTangents(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f) -> mat2x3f {
204
+ let d0 = rzKnot(p0, p1);
205
+ let d1 = rzKnot(p1, p2);
206
+ let d2 = rzKnot(p2, p3);
207
+ let m1 = ((p1 - p0) / d0 - (p2 - p0) / (d0 + d1) + (p2 - p1) / d1) * d1;
208
+ let m2 = ((p2 - p1) / d1 - (p3 - p1) / (d1 + d2) + (p3 - p2) / d2) * d1;
209
+ return mat2x3f(m1, m2);
210
+ }
211
+
182
212
  /** Catmull-Rom through four samples — passes through p1 and p2. */
183
213
  fn rzSpline(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f, t: f32) -> vec3f {
214
+ let m = rzSplineTangents(p0, p1, p2, p3);
184
215
  let t2 = t * t;
185
216
  let t3 = t2 * t;
186
- return 0.5 * ((2.0 * p1) + (-p0 + p2) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
187
- (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
217
+ return (2.0 * t3 - 3.0 * t2 + 1.0) * p1
218
+ + (t3 - 2.0 * t2 + t) * m[0]
219
+ + (-2.0 * t3 + 3.0 * t2) * p2
220
+ + (t3 - t2) * m[1];
188
221
  }
189
- /** Its derivative — the ribbon's direction, smooth by construction. */
222
+
223
+ /**
224
+ * Its derivative — the ribbon's direction, smooth by construction.
225
+ *
226
+ * Still exact at the knots, which is what the shared edge depends on: at t = 1
227
+ * this is m2 and at t = 0 it is m1, and the two segments meeting at a sample
228
+ * derive those from the same three points. They differ only by a positive
229
+ * scale, and this normalises, so both quads get the identical direction.
230
+ */
190
231
  fn rzSplineTangent(p0: vec3f, p1: vec3f, p2: vec3f, p3: vec3f, t: f32) -> vec3f {
232
+ let m = rzSplineTangents(p0, p1, p2, p3);
191
233
  let t2 = t * t;
192
- let d = 0.5 * ((-p0 + p2) + 2.0 * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t +
193
- 3.0 * (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t2);
234
+ let d = (6.0 * t2 - 6.0 * t) * p1
235
+ + (3.0 * t2 - 4.0 * t + 1.0) * m[0]
236
+ + (-6.0 * t2 + 6.0 * t) * p2
237
+ + (3.0 * t2 - 2.0 * t) * m[1];
194
238
  if (length(d) < 1e-6) { return vec3f(0.0, 1.0, 0.0); }
195
239
  return normalize(d);
196
240
  }