reze-engine 0.68.4 → 0.68.6

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.
@@ -222,7 +222,7 @@ fn _rzCastShadow(wp: vec3f) -> f32 {
222
222
  // [1] right iris centre, scale bounce (both eyes)
223
223
  // [2] left iris half extents, closure, eye bone (−1 none)
224
224
  // [3] the right's
225
- // [4] left squash, 0, 0, shine [5] the right's
225
+ // [4] left squash, 0, clock, shine [5] the right's
226
226
  struct ObjectLight { layers: vec4u, ambient: vec4f, sh: array<vec4f, 9>, fill: vec4f, jelly: array<vec4f, 6> }
227
227
  @group(1) @binding(1) var<uniform> objectLight: ObjectLight;
228
228
 
@@ -234,12 +234,14 @@ struct RzJelly {
234
234
  w: f32,
235
235
  closure: f32,
236
236
  shine: f32,
237
+ /** Scene seconds (wrapped), for the twinkles. */
238
+ clock: f32,
237
239
  };
238
240
 
239
241
  /**
240
242
  * Where the jelly puts an iris vertex. The iris is the part of the eye the eye
241
243
  * bones carry, so it is moved as a whole, in bind space before skinning:
242
- * flattened about its centre while the eye closes, bulging across as jelly does,
244
+ * shrunk about its centre while a lid moves, a little more down than across,
243
245
  * grown past rest as it springs back, and swelling as a turn or her motion
244
246
  * knocks it — scale only, in place, inside the white, which stays where it is. Vertices take it by
245
247
  * their weight on the eye bones (jelly[2].w, jelly[3].w), so nothing else on
@@ -259,10 +261,11 @@ fn rzJellyVertex(p: vec3f, joints: vec4<u32>, nw: vec4f) -> vec3f {
259
261
  if (j[2].w == j[3].w && e == 0u && distance(p.xy, j[1].xy) < distance(p.xy, j[0].xy)) { continue; }
260
262
  if (j[2].w == j[3].w && e == 1u && distance(p.xy, j[0].xy) <= distance(p.xy, j[1].xy)) { continue; }
261
263
  let st = j[4u + e];
262
- // The blink's squash, as jelly gives: flattened down, it bulges across
263
- // (and a stretch thins it), and the bounce both eyes share (jelly[1].w).
264
- // Height is held under 1.06 so a swell cannot rise past the upper lid.
265
- let k = clamp(vec2f(1.0 + 0.45 * st.x, 1.0 - st.x) + j[1].w, vec2f(0.9, 0.78), vec2f(1.1, 1.06));
264
+ // The squash, nearly round: it shrinks both ways, a little more down than
265
+ // across, so the iris keeps its circle and only leans oval; and the bounce
266
+ // both eyes share (jelly[1].w). Held under 1.08 so a swell cannot rise
267
+ // past the upper lid.
268
+ let k = clamp(vec2f(1.0 - 0.8 * st.x, 1.0 - st.x) + j[1].w, vec2f(0.78, 0.75), vec2f(1.08, 1.08));
266
269
  let moved = c.xy + (p.xy - c.xy) * k;
267
270
  out = vec3f(mix(p.xy, moved, w), p.z);
268
271
  }
@@ -282,7 +285,7 @@ fn rzJellyEye(rp: vec3f) -> RzJelly {
282
285
  let a = select(qL, qR, right);
283
286
  let st = select(j[4], j[5], right);
284
287
  let w = (1.0 - smoothstep(0.85, 1.0, length(a))) * select(0.0, 1.0, j[0].w > 0.0);
285
- return RzJelly(a, w, select(j[2].z, j[3].z, right), st.w);
288
+ return RzJelly(a, w, select(j[2].z, j[3].z, right), st.w, j[4].z);
286
289
  }
287
290
 
288
291
  /**
@@ -304,37 +307,85 @@ fn rzJellyGlow(jj: RzJelly, tex: vec3f, alpha: f32, v: vec3f, l: vec3f, sun: vec
304
307
  fwd = -normalize(hm[2].xyz);
305
308
  }
306
309
  let h = normalize(l + v);
307
- // Held near the middle of the iris, a little low: the top of an iris sits
308
- // under the upper lid, and a glint there pokes out over it.
310
+ // Held in the middle and lower iris: the top of an iris sits under the upper
311
+ // lid, and a glint there — or its bloom halo — pokes out over it.
309
312
  var g = vec2f(dot(h, right), dot(h, up)) * 0.6;
310
- g = g * min(1.0, 0.3 / max(length(g), 1e-6)) - vec2f(0.0, 0.08);
313
+ g = g * min(1.0, 0.25 / max(length(g), 1e-6)) - vec2f(0.0, 0.1);
314
+ g.y = min(g.y, 0.0);
311
315
  let aa = max(length(fwidth(jj.src)), 1e-4);
312
- let glint = 1.0 - smoothstep(0.16 - aa, 0.16 + aa, distance(jj.src, g));
316
+ // A star, not only a disc: the disc with two thin rays through it, the
317
+ // anime sparkle.
318
+ let dg = jj.src - g;
319
+ let rays = max(0.0, 1.0 - abs(dg.y) / 0.018) * (1.0 - smoothstep(0.0, 0.34, abs(dg.x)))
320
+ + max(0.0, 1.0 - abs(dg.x) / 0.018) * (1.0 - smoothstep(0.0, 0.26, abs(dg.y)));
321
+ let glint = max(1.0 - smoothstep(0.13 - aa, 0.13 + aa, length(dg)), rays * 0.8);
313
322
  let second = 1.0 - smoothstep(0.07 - aa, 0.07 + aa, distance(jj.src, -0.55 * g + vec2f(0.1, -0.12)));
314
323
  let facing = saturate(dot(fwd, v) * 2.0);
315
324
  let key = clamp(dot(sun, vec3f(0.2126, 0.7152, 0.0722)), 0.3, 2.0);
316
325
  let lit = facing * key * (0.35 + 0.65 * shadow);
317
326
  // HDR, well past 1, so bloom takes them as the hard sparkle of a gem.
318
- let glints = (glint + 0.8 * second) * lit * (2.6 + 1.6 * jj.shine);
319
- let open = 1.0 - smoothstep(0.3, 0.8, jj.closure);
327
+ // Bright enough for bloom to catch, not so bright its halo spreads past the
328
+ // iris onto the lid.
329
+ let glints = (glint + 0.8 * second) * lit * (1.8 + 0.8 * jj.shine);
330
+ // Gone as the lid starts down, not only once shut: a half-closed smile puts
331
+ // the lid right over where the glint sits.
332
+ let open = 1.0 - smoothstep(0.1, 0.45, jj.closure);
320
333
  // Only where the eye's own picture is (its alpha), never on the iris's top
321
334
  // rim, and gone as the lid comes down.
322
- let onEye = smoothstep(0.5, 0.9, alpha) * (1.0 - smoothstep(0.35, 0.6, jj.src.y));
335
+ let solid = smoothstep(0.5, 0.9, alpha);
336
+ let onEye = solid * (1.0 - smoothstep(0.05, 0.35, jj.src.y));
323
337
  // Light through the jelly: the light enters where the glint is and comes out
324
338
  // the far side, so the iris glows in its own colour in a crescent opposite
325
339
  // the glint — the lit-from-within look of a gem, or a jelly.
326
340
  let r = length(jj.src);
327
- let away = -normalize(g + vec2f(0.0, -1e-3));
341
+ // Out the LOWER iris, always — the anime gem's bright underside — leaning
342
+ // away from the glint; never up, where its bloom would spill on the lid.
343
+ let away = normalize(vec2f(-g.x * 0.6, -1.0));
328
344
  let crescent = smoothstep(0.15, 0.7, dot(jj.src, away)) * (1.0 - smoothstep(0.8, 1.0, r));
329
- let through = tex * crescent * (0.9 + 0.6 * jj.shine) * lit;
345
+ let through = tex * crescent * (2.2 + 1.0 * jj.shine) * lit;
330
346
  // And the colour runs deeper: the iris's own hue pushed, never its greys.
331
347
  let lum = dot(tex, vec3f(0.2126, 0.7152, 0.0722));
332
- let vivid = max(tex - vec3f(lum), vec3f(0.0)) * 0.7;
333
- let gem = (vec3f(glints) + through + vivid) * open * onEye * jj.w;
348
+ let vivid = max(tex - vec3f(lum), vec3f(0.0)) * 1.2;
349
+ // The glass over it: a broad soft sheen across the upper iris, under the
350
+ // lid line, the dome of a bead catching the room.
351
+ let dome = (1.0 - smoothstep(0.0, 0.5, distance(jj.src * vec2f(0.8, 1.4), vec2f(0.0, 0.2)))) * 0.45 * lit;
352
+ // Everything that blooms keeps to the lower iris, so no halo reaches the lid.
353
+ let lower = 1.0 - smoothstep(-0.05, 0.3, jj.src.y);
354
+ // The cut: soft facets fanning across the lower iris, light split as a cut
355
+ // stone splits it, turning slowly.
356
+ let ang = atan2(jj.src.y, jj.src.x);
357
+ let facets = pow(0.5 + 0.5 * cos(ang * 7.0 + jj.clock * 0.35), 6.0)
358
+ * smoothstep(0.3, 0.75, r) * (1.0 - smoothstep(0.82, 0.97, r)) * lower;
359
+ // The rim: a band of its own colour just inside the iris edge, HDR, which
360
+ // bloom spreads into a glow around the stone.
361
+ let rim = smoothstep(0.7, 0.84, r) * (1.0 - smoothstep(0.86, 0.97, r)) * lower;
362
+ // Twinkles: three specks in the lower iris, each flashing now and then on
363
+ // the scene clock.
364
+ var twinkle = 0.0;
365
+ for (var i = 0; i < 3; i++) {
366
+ let fi = f32(i);
367
+ let at = vec2f(0.42 * cos(3.6 + fi * 1.1), -0.25 - 0.18 * fi + 0.1 * sin(fi * 2.3));
368
+ let flash = pow(max(0.0, sin(jj.clock * (1.3 + 0.37 * fi) + fi * 2.1)), 12.0);
369
+ twinkle += (1.0 - smoothstep(0.0, 0.05 + aa, distance(jj.src, at))) * flash;
370
+ }
371
+ let sparkle = (vec3f(glints + twinkle * 2.0) * onEye
372
+ + tex * facets * 2.5 * lit * solid * (1.0 + 0.6 * jj.shine));
373
+ // The soft light (sheen, glow through, colour) needs only the eye's picture.
374
+ let gem = (sparkle + (vec3f(dome) + through + vivid) * solid) * open * jj.w;
375
+ // The edge, which jj.w (fading out from 0.85) would hide: the glowing rim
376
+ // band, and a thin glossy line right at the border — light running round
377
+ // the stone's edge — all the way round, bright below and dim above, where a
378
+ // halo would reach the lid. Up to the mesh's edge and no further.
379
+ let on = select(0.0, 1.0, strength > 0.0) * (1.0 - smoothstep(1.0 - aa, 1.0, r));
380
+ let edgeLine = smoothstep(0.92, 0.955, r) * (1.0 - smoothstep(0.965, 0.995, r));
381
+ let edgeLit = mix(0.3, 1.0, lower) * lit * (1.0 + 0.6 * jj.shine);
382
+ let edge = (tex * rim * 2.0 + vec3f(rim * 0.25)) * lit * (1.0 + 0.6 * jj.shine)
383
+ + (vec3f(0.55) + tex * 0.8) * edgeLine * edgeLit;
384
+ let border = edge * solid * open * on;
334
385
  // The whole eye shines a little brighter, more while it wobbles — not just
335
386
  // the iris, so this one is not held to it (jj.w).
336
- let lift = tex * (0.15 + 0.35 * jj.shine) * select(0.0, 1.0, strength > 0.0);
337
- return (gem + lift) * min(strength, 1.0);
387
+ let lift = tex * (0.25 + 0.35 * jj.shine) * select(0.0, 1.0, strength > 0.0);
388
+ return (gem + border + lift) * min(strength, 1.0);
338
389
  }
339
390
 
340
391
  /** The light arriving at a surface of this object facing n: its own ambient