vireuikit 0.2.0 → 0.4.0
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.
- package/README.md +47 -15
- package/dist/{chunk-BV5P6MF7.js → chunk-VY22O2II.js} +485 -46
- package/dist/chunk-VY22O2II.js.map +1 -0
- package/dist/{dynamics-DelasYER.d.cts → dynamics-DqGk_f1n.d.cts} +170 -14
- package/dist/{dynamics-DelasYER.d.ts → dynamics-DqGk_f1n.d.ts} +170 -14
- package/dist/index.cjs +434 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +1 -1
- package/dist/web/index.cjs +984 -145
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +63 -2
- package/dist/web/index.d.ts +63 -2
- package/dist/web/index.js +462 -13
- package/dist/web/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BV5P6MF7.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -274,9 +274,46 @@ function neutralSpecies(baseColor) {
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
// src/medium/params.ts
|
|
277
|
+
var MEDIUM_MAX_LIGHTS = 3;
|
|
277
278
|
var BASE_COLOR = [0.07, 0.08, 0.1];
|
|
279
|
+
var normalize2 = (v) => {
|
|
280
|
+
const len = Math.hypot(v[0], v[1]) || 1;
|
|
281
|
+
return [v[0] / len, v[1] / len];
|
|
282
|
+
};
|
|
283
|
+
var MEDIUM_DEFAULT_LIGHT_COLOR = [0.78, 0.85, 0.94];
|
|
284
|
+
var MEDIUM_DEFAULT_LIGHTS = [
|
|
285
|
+
{
|
|
286
|
+
position: [0.5, 0],
|
|
287
|
+
direction: [0, 1],
|
|
288
|
+
coneAngle: Math.PI,
|
|
289
|
+
falloff: 16,
|
|
290
|
+
color: MEDIUM_DEFAULT_LIGHT_COLOR,
|
|
291
|
+
intensity: 0.28
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
position: [0.12, 1.45],
|
|
295
|
+
direction: normalize2([0.38, -1.03]),
|
|
296
|
+
coneAngle: 9 * Math.PI / 180,
|
|
297
|
+
falloff: 0.7,
|
|
298
|
+
color: MEDIUM_DEFAULT_LIGHT_COLOR,
|
|
299
|
+
intensity: 1.1
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
position: [0.9, 1.4],
|
|
303
|
+
direction: normalize2([-0.4, -0.98]),
|
|
304
|
+
coneAngle: 8 * Math.PI / 180,
|
|
305
|
+
falloff: 0.75,
|
|
306
|
+
color: MEDIUM_DEFAULT_LIGHT_COLOR,
|
|
307
|
+
intensity: 0.9
|
|
308
|
+
}
|
|
309
|
+
];
|
|
278
310
|
var MEDIUM_DEFAULTS = {
|
|
279
|
-
|
|
311
|
+
// A stamped track has to visibly broaden and fade within the reference's "roughly one to two
|
|
312
|
+
// seconds", not the ~11s half-life a 0.06 decay gives — measured against check-medium.mjs's track
|
|
313
|
+
// gate (birth vs +1.5s cross-section width and total density): 1.1 leaves ~30% of the peak at 1s
|
|
314
|
+
// and ~17% at 1.5s, comfortably faded without dying before MacCormack's own diffusion has time to
|
|
315
|
+
// visibly broaden the stamp.
|
|
316
|
+
decay: 1.1,
|
|
280
317
|
curlFreq: 0.045,
|
|
281
318
|
curlSpeed: 0.12,
|
|
282
319
|
advectSpeed: 26,
|
|
@@ -285,11 +322,13 @@ var MEDIUM_DEFAULTS = {
|
|
|
285
322
|
condensationFloor: 0.12,
|
|
286
323
|
evaporationRate: 0.2,
|
|
287
324
|
condensateSettleSpeed: 8,
|
|
325
|
+
condensateSettleWiggle: 0.4,
|
|
288
326
|
condensateSpreadRate: 0.08,
|
|
289
327
|
condensateTint: 0.2,
|
|
290
328
|
condensateGain: 5,
|
|
291
329
|
condensateColor: [0.94, 0.95, 0.97],
|
|
292
330
|
channelColors: neutralSpecies(BASE_COLOR),
|
|
331
|
+
channelScatter: [1, 1, 1],
|
|
293
332
|
baseColor: BASE_COLOR,
|
|
294
333
|
baseWeight: 0.9,
|
|
295
334
|
depthFarScale: 1.6,
|
|
@@ -298,7 +337,11 @@ var MEDIUM_DEFAULTS = {
|
|
|
298
337
|
depthFarWeight: 0.5,
|
|
299
338
|
gravityVaporDrift: 0.6,
|
|
300
339
|
gravityBottomBoost: 2,
|
|
301
|
-
gravityBottomBoostStart: 0.75
|
|
340
|
+
gravityBottomBoostStart: 0.75,
|
|
341
|
+
lights: MEDIUM_DEFAULT_LIGHTS,
|
|
342
|
+
shadowExtinction: 3,
|
|
343
|
+
trackLightFloor: 0.8,
|
|
344
|
+
trackLayerAmount: 1
|
|
302
345
|
};
|
|
303
346
|
function depthFarOffsetPx(offsetFrac, gridWidth, gridHeight) {
|
|
304
347
|
return [offsetFrac[0] * gridWidth, offsetFrac[1] * gridHeight];
|
|
@@ -320,7 +363,7 @@ var MEDIUM_TRACK_PRESETS = {
|
|
|
320
363
|
tailDim: 0.55,
|
|
321
364
|
intensity: 1.15
|
|
322
365
|
},
|
|
323
|
-
|
|
366
|
+
electron: {
|
|
324
367
|
lengthFrac: 0.42,
|
|
325
368
|
headWidthFrac: 0.018,
|
|
326
369
|
tailWidthFrac: 0.05,
|
|
@@ -328,17 +371,17 @@ var MEDIUM_TRACK_PRESETS = {
|
|
|
328
371
|
raggedFreq: 5,
|
|
329
372
|
settleFrac: 0.05,
|
|
330
373
|
tailDim: 0.45,
|
|
331
|
-
intensity: 0.
|
|
374
|
+
intensity: 0.6
|
|
332
375
|
},
|
|
333
|
-
|
|
334
|
-
lengthFrac: 0.
|
|
335
|
-
headWidthFrac: 0.
|
|
336
|
-
tailWidthFrac: 0.
|
|
337
|
-
raggedFrac: 0
|
|
338
|
-
raggedFreq:
|
|
339
|
-
settleFrac: 0.
|
|
340
|
-
tailDim: 0.
|
|
341
|
-
intensity: 0.
|
|
376
|
+
muon: {
|
|
377
|
+
lengthFrac: 0.7,
|
|
378
|
+
headWidthFrac: 0.012,
|
|
379
|
+
tailWidthFrac: 0.02,
|
|
380
|
+
raggedFrac: 0,
|
|
381
|
+
raggedFreq: 0,
|
|
382
|
+
settleFrac: 0.01,
|
|
383
|
+
tailDim: 0.75,
|
|
384
|
+
intensity: 0.5
|
|
342
385
|
}
|
|
343
386
|
};
|
|
344
387
|
var MEDIUM_DRIFT_TURBULENCE = 0.045;
|
|
@@ -347,12 +390,60 @@ var MEDIUM_TURBULENCE_TAU = 2.5;
|
|
|
347
390
|
var MEDIUM_EMISSION_BEATS = 4;
|
|
348
391
|
var MEDIUM_EMISSION_PROBABILITY = 0.55;
|
|
349
392
|
var MEDIUM_MIN_EMISSION_INTERVAL = 1.2;
|
|
350
|
-
var MEDIUM_NATURAL_INTERVAL =
|
|
351
|
-
var MEDIUM_NATURAL_JITTER =
|
|
393
|
+
var MEDIUM_NATURAL_INTERVAL = 8;
|
|
394
|
+
var MEDIUM_NATURAL_JITTER = 12;
|
|
352
395
|
var MEDIUM_SENSITIVE_TOP = 0.55;
|
|
353
396
|
var MEDIUM_SENSITIVE_BOTTOM = 0.95;
|
|
354
|
-
var
|
|
397
|
+
var MEDIUM_ALPHA_BURST_RAYS = [8, 16];
|
|
398
|
+
var MEDIUM_ALPHA_RAY_LENGTH_SCALE = [0.55, 1];
|
|
399
|
+
var MEDIUM_TRACK_DEPTH_WIDTH_RANGE = [0.55, 1.2];
|
|
355
400
|
var MEDIUM_TRACK_DEPTH_INTENSITY_RANGE = [0.4, 1];
|
|
401
|
+
var MEDIUM_TRACK_LAYER_LIFE_SECONDS = {
|
|
402
|
+
alpha: 1.8,
|
|
403
|
+
electron: 1.4,
|
|
404
|
+
muon: 2.2
|
|
405
|
+
};
|
|
406
|
+
var MEDIUM_TRACK_LAYER_MAX_TRACKS = 64;
|
|
407
|
+
var MEDIUM_TRACK_LAYER_LOOK = {
|
|
408
|
+
alpha: {
|
|
409
|
+
sigmaFrac: 22e-4,
|
|
410
|
+
endSigmaMul: 1.9,
|
|
411
|
+
broaden: 3.2,
|
|
412
|
+
wiggleFrac: 0,
|
|
413
|
+
beadFrac: 6e-3,
|
|
414
|
+
dropletFrac: 35e-4,
|
|
415
|
+
dropletChance: 0.5,
|
|
416
|
+
startFrac: 0.035,
|
|
417
|
+
gain: 1.8
|
|
418
|
+
},
|
|
419
|
+
electron: {
|
|
420
|
+
sigmaFrac: 9e-4,
|
|
421
|
+
endSigmaMul: 1.3,
|
|
422
|
+
broaden: 6,
|
|
423
|
+
wiggleFrac: 0.012,
|
|
424
|
+
beadFrac: 8e-3,
|
|
425
|
+
dropletFrac: 6e-3,
|
|
426
|
+
dropletChance: 0.55,
|
|
427
|
+
startFrac: 0,
|
|
428
|
+
gain: 2.2
|
|
429
|
+
},
|
|
430
|
+
muon: {
|
|
431
|
+
sigmaFrac: 8e-4,
|
|
432
|
+
endSigmaMul: 1,
|
|
433
|
+
broaden: 5,
|
|
434
|
+
wiggleFrac: 0,
|
|
435
|
+
beadFrac: 7e-3,
|
|
436
|
+
dropletFrac: 5e-3,
|
|
437
|
+
dropletChance: 0.5,
|
|
438
|
+
startFrac: 0,
|
|
439
|
+
gain: 2.2
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
var MEDIUM_TRACK_LAYER_BURST_SPREAD = 1.6;
|
|
443
|
+
var MEDIUM_TRACK_LAYER_BURST_ACCENT = 3;
|
|
444
|
+
var MEDIUM_TRACK_LAYER_FADE_GAMMA = 1.6;
|
|
445
|
+
var MEDIUM_TRACK_LAYER_GRAVITY_SAG = 0.018;
|
|
446
|
+
var MEDIUM_TRACK_LAYER_CURL_PUSH = 0.05;
|
|
356
447
|
|
|
357
448
|
// src/medium/noise.ts
|
|
358
449
|
var VG_VALUE_NOISE = `
|
|
@@ -484,6 +575,71 @@ float2 vgCurlVelocity(float2 p, float phase) {
|
|
|
484
575
|
float py0 = vgPotential(p - float2(0.0, e), phase);
|
|
485
576
|
return float2(py1 - py0, -(px1 - px0)) / (2.0 * e);
|
|
486
577
|
}
|
|
578
|
+
|
|
579
|
+
// vgPotential above is periodic in TIME only: the simulation domain is a torus (gl.REPEAT), but
|
|
580
|
+
// the lattice itself never wraps in x/y, so velocity jumps at the domain seam and dye on either
|
|
581
|
+
// side of it is transported differently \u2014 a straight seam, made worse wherever something re-reads
|
|
582
|
+
// the field at a different scale (the far depth plane's tile boundary). vgValueNoise3Seamless
|
|
583
|
+
// wraps ALL THREE lattice axes: xyPeriod/zPeriod fold BOTH neighbors of a cell into their own
|
|
584
|
+
// period before hashing, so the field is EXACTLY the same one period over, in space exactly as it
|
|
585
|
+
// already was in time.
|
|
586
|
+
//
|
|
587
|
+
// The period has to be an integer number of lattice cells, or the wrap would jump instead of
|
|
588
|
+
// closing seamlessly (the same requirement MEDIUM_TIME_OCTAVES/mediumOctavePeriod enforces for
|
|
589
|
+
// time) \u2014 but unlike time, the spatial period depends on the GRID SIZE, which this shader has no
|
|
590
|
+
// notion of. So xyPeriod travels together with a per-octave spatial frequency the CPU computes to
|
|
591
|
+
// make gridSize * frequency land on that exact integer (see computeMediumSpatialPeriods below);
|
|
592
|
+
// both arrive together as one uniform per octave (u_spatialN.xy = frequency, .zw = period),
|
|
593
|
+
// recomputed by web/medium.ts whenever the grid resizes.
|
|
594
|
+
float vgValueNoise3Seamless(float3 p, float2 xyPeriod, float zPeriod) {
|
|
595
|
+
float3 i = floor(p);
|
|
596
|
+
float3 f = fract(p);
|
|
597
|
+
float3 u = f * f * (3.0 - 2.0 * f);
|
|
598
|
+
float x0 = mod(i.x, xyPeriod.x);
|
|
599
|
+
float x1 = mod(i.x + 1.0, xyPeriod.x);
|
|
600
|
+
float y0 = mod(i.y, xyPeriod.y);
|
|
601
|
+
float y1 = mod(i.y + 1.0, xyPeriod.y);
|
|
602
|
+
float z0 = mod(i.z, zPeriod);
|
|
603
|
+
float z1 = mod(i.z + 1.0, zPeriod);
|
|
604
|
+
float n000 = vgHash31(float3(x0, y0, z0));
|
|
605
|
+
float n100 = vgHash31(float3(x1, y0, z0));
|
|
606
|
+
float n010 = vgHash31(float3(x0, y1, z0));
|
|
607
|
+
float n110 = vgHash31(float3(x1, y1, z0));
|
|
608
|
+
float n001 = vgHash31(float3(x0, y0, z1));
|
|
609
|
+
float n101 = vgHash31(float3(x1, y0, z1));
|
|
610
|
+
float n011 = vgHash31(float3(x0, y1, z1));
|
|
611
|
+
float n111 = vgHash31(float3(x1, y1, z1));
|
|
612
|
+
float nx00 = mix(n000, n100, u.x);
|
|
613
|
+
float nx10 = mix(n010, n110, u.x);
|
|
614
|
+
float nx01 = mix(n001, n101, u.x);
|
|
615
|
+
float nx11 = mix(n011, n111, u.x);
|
|
616
|
+
float nxy0 = mix(nx00, nx10, u.y);
|
|
617
|
+
float nxy1 = mix(nx01, nx11, u.y);
|
|
618
|
+
return mix(nxy0, nxy1, u.z) * 2.0 - 1.0;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// Same four-octave fbm as vgPotential, but every octave reads the seamless lattice above at its
|
|
622
|
+
// OWN (frequency, period) pair \u2014 sN.xy replaces that octave's compile-time \`scale\` constant (it
|
|
623
|
+
// has to be a uniform now: the adjustment depends on the live grid size), sN.zw is the matching
|
|
624
|
+
// integer period. \`p\` is still curlFreq-scaled exactly as vgPotential's caller scales it \u2014 only
|
|
625
|
+
// the per-octave multiplier changed from a constant to a grid-dependent uniform, so the finite
|
|
626
|
+
// difference in vgCurlVelocitySeamless below needs no epsilon change of its own.
|
|
627
|
+
float vgPotentialSeamless(float2 p, float phase, float4 s0, float4 s1, float4 s2, float4 s3) {
|
|
628
|
+
float v = vgValueNoise3Seamless(float3(p * s0.xy, phase * ${VG_OCT0.rate} + ${VG_OCT0.offset}), s0.zw, ${VG_OCT0.period}) * 0.5;
|
|
629
|
+
v += vgValueNoise3Seamless(float3(p * s1.xy, phase * ${VG_OCT1.rate} + ${VG_OCT1.offset}), s1.zw, ${VG_OCT1.period}) * 0.25;
|
|
630
|
+
v += vgValueNoise3Seamless(float3(p * s2.xy, phase * ${VG_OCT2.rate} + ${VG_OCT2.offset}), s2.zw, ${VG_OCT2.period}) * 0.125;
|
|
631
|
+
float macro = vgValueNoise3Seamless(float3(p * s3.xy, phase * ${VG_OCT3.rate} + ${VG_OCT3.offset}), s3.zw, ${VG_OCT3.period});
|
|
632
|
+
return v * (0.7 + 0.3 * macro);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
float2 vgCurlVelocitySeamless(float2 p, float phase, float4 s0, float4 s1, float4 s2, float4 s3) {
|
|
636
|
+
float e = 0.6;
|
|
637
|
+
float px1 = vgPotentialSeamless(p + float2(e, 0.0), phase, s0, s1, s2, s3);
|
|
638
|
+
float px0 = vgPotentialSeamless(p - float2(e, 0.0), phase, s0, s1, s2, s3);
|
|
639
|
+
float py1 = vgPotentialSeamless(p + float2(0.0, e), phase, s0, s1, s2, s3);
|
|
640
|
+
float py0 = vgPotentialSeamless(p - float2(0.0, e), phase, s0, s1, s2, s3);
|
|
641
|
+
return float2(py1 - py0, -(px1 - px0)) / (2.0 * e);
|
|
642
|
+
}
|
|
487
643
|
`;
|
|
488
644
|
|
|
489
645
|
// src/medium/seed-shader.ts
|
|
@@ -527,15 +683,25 @@ uniform float u_phase;
|
|
|
527
683
|
uniform float u_curlFreq;
|
|
528
684
|
uniform float u_advectSpeed;
|
|
529
685
|
uniform float u_turbulence;
|
|
686
|
+
// One float4 per MEDIUM_TIME_OCTAVES entry: xy is that octave's seamless spatial frequency, zw its
|
|
687
|
+
// matching integer lattice period \u2014 both grid-size-dependent, so they can't be compile-time
|
|
688
|
+
// constants (see vgPotentialSeamless/computeMediumSpatialPeriods in noise.ts). Recomputed by
|
|
689
|
+
// web/medium.ts's bindVelocityUniforms every frame from the live grid dimensions.
|
|
690
|
+
uniform float4 u_spatial0;
|
|
691
|
+
uniform float4 u_spatial1;
|
|
692
|
+
uniform float4 u_spatial2;
|
|
693
|
+
uniform float4 u_spatial3;
|
|
530
694
|
|
|
531
695
|
${VG_CURL_NOISE}
|
|
532
696
|
`;
|
|
533
697
|
var MEDIUM_ADVECT_VELOCITY = `
|
|
534
|
-
float2
|
|
698
|
+
float2 curl = vgCurlVelocitySeamless(xy * u_curlFreq, u_phase, u_spatial0, u_spatial1, u_spatial2, u_spatial3);
|
|
699
|
+
float2 vel = curl * u_advectSpeed * u_turbulence;
|
|
535
700
|
`;
|
|
536
701
|
var MEDIUM_ADVECT_VELOCITY_SETTLE = `
|
|
537
702
|
${MEDIUM_ADVECT_VELOCITY}
|
|
538
703
|
vel.y += u_settleSpeed;
|
|
704
|
+
vel.x += curl.x * u_advectSpeed * u_settleWiggle;
|
|
539
705
|
`;
|
|
540
706
|
var MEDIUM_ADVECT_VELOCITY_VAPOR = `
|
|
541
707
|
${MEDIUM_ADVECT_VELOCITY}
|
|
@@ -554,6 +720,7 @@ ${MEDIUM_ADVECT_VELOCITY_VAPOR}
|
|
|
554
720
|
var MEDIUM_CONDENSATE_FORWARD_SHADER = `
|
|
555
721
|
${MEDIUM_ADVECT_UNIFORMS}
|
|
556
722
|
uniform float u_settleSpeed;
|
|
723
|
+
uniform float u_settleWiggle;
|
|
557
724
|
|
|
558
725
|
half4 main(float2 xy) {
|
|
559
726
|
${MEDIUM_ADVECT_VELOCITY_SETTLE}
|
|
@@ -593,6 +760,7 @@ ${MEDIUM_MACCORMACK_CORRECT}
|
|
|
593
760
|
var MEDIUM_CONDENSATE_CORRECT_SHADER = `
|
|
594
761
|
${MEDIUM_ADVECT_UNIFORMS}
|
|
595
762
|
uniform float u_settleSpeed;
|
|
763
|
+
uniform float u_settleWiggle;
|
|
596
764
|
uniform shader u_forward;
|
|
597
765
|
|
|
598
766
|
half4 main(float2 xy) {
|
|
@@ -692,10 +860,68 @@ ${MEDIUM_ADVECT_VELOCITY}
|
|
|
692
860
|
`;
|
|
693
861
|
|
|
694
862
|
// src/medium/composite-shader.ts
|
|
863
|
+
var VG_CUBIC_WEIGHTS = `
|
|
864
|
+
float4 vgCubicWeights(float v) {
|
|
865
|
+
float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
|
|
866
|
+
float4 s = n * n * n;
|
|
867
|
+
float x = s.x;
|
|
868
|
+
float y = s.y - 4.0 * s.x;
|
|
869
|
+
float z = s.z - 4.0 * s.y + 6.0 * s.x;
|
|
870
|
+
float w = 6.0 - x - y - z;
|
|
871
|
+
return float4(x, y, z, w) * (1.0 / 6.0);
|
|
872
|
+
}
|
|
873
|
+
`;
|
|
874
|
+
function vgBicubicSampler(fnName, textureName) {
|
|
875
|
+
return `
|
|
876
|
+
half4 ${fnName}(float2 px) {
|
|
877
|
+
float2 shifted = px - 0.5;
|
|
878
|
+
float2 fxy = fract(shifted);
|
|
879
|
+
float2 base = shifted - fxy;
|
|
880
|
+
float4 xw = vgCubicWeights(fxy.x);
|
|
881
|
+
float4 yw = vgCubicWeights(fxy.y);
|
|
882
|
+
float2 sx = float2(xw.x + xw.y, xw.z + xw.w);
|
|
883
|
+
float2 sy = float2(yw.x + yw.y, yw.z + yw.w);
|
|
884
|
+
float2 offsetX = float2(base.x - 0.5 + xw.y / sx.x, base.x + 1.5 + xw.w / sx.y);
|
|
885
|
+
float2 offsetY = float2(base.y - 0.5 + yw.y / sy.x, base.y + 1.5 + yw.w / sy.y);
|
|
886
|
+
half4 s00 = ${textureName}.eval(float2(offsetX.x, offsetY.x));
|
|
887
|
+
half4 s10 = ${textureName}.eval(float2(offsetX.y, offsetY.x));
|
|
888
|
+
half4 s01 = ${textureName}.eval(float2(offsetX.x, offsetY.y));
|
|
889
|
+
half4 s11 = ${textureName}.eval(float2(offsetX.y, offsetY.y));
|
|
890
|
+
float wx = sx.x / (sx.x + sx.y);
|
|
891
|
+
float wy = sy.x / (sy.x + sy.y);
|
|
892
|
+
return mix(mix(s11, s01, wx), mix(s10, s00, wx), wy);
|
|
893
|
+
}
|
|
894
|
+
`;
|
|
895
|
+
}
|
|
896
|
+
var VG_LIGHT = `
|
|
897
|
+
float vgLightAmount(float2 xy, float2 lightPosFrac, float2 lightDir, float cosCone, float falloff, float2 resolution, float seed) {
|
|
898
|
+
float2 rel = xy - lightPosFrac * resolution;
|
|
899
|
+
// A cone of 180\xB0 or more is an edge strip: light spreads from a line, not a point.
|
|
900
|
+
if (cosCone <= -0.999) {
|
|
901
|
+
float depth = max(dot(rel, lightDir), 0.0);
|
|
902
|
+
return exp(-(depth / max(resolution.y, 1.0)) * falloff);
|
|
903
|
+
}
|
|
904
|
+
float dist = length(rel);
|
|
905
|
+
float2 dirN = dist > 1e-4 ? rel / dist : lightDir;
|
|
906
|
+
float cosAngle = dot(dirN, lightDir);
|
|
907
|
+
// A soft lobe with half intensity at the cone angle and no boundary at all: a lamp in haze has
|
|
908
|
+
// no drawn edge.
|
|
909
|
+
float lobe = log(0.5) / log(clamp(cosCone, 0.05, 0.999));
|
|
910
|
+
float edge = pow(max(cosAngle, 0.0), lobe);
|
|
911
|
+
float atten = exp(-(dist / max(resolution.y, 1.0)) * falloff);
|
|
912
|
+
if (edge * atten < 0.001) return 0.0;
|
|
913
|
+
// Static shafts inside the beam: brightness varies with the angle around the lamp, so streaks
|
|
914
|
+
// fan out from the source the way light through dusty air does.
|
|
915
|
+
float angle = atan(dirN.x * lightDir.y - dirN.y * lightDir.x, cosAngle);
|
|
916
|
+
float shafts = 0.6 + 0.32 * vgValueNoise(float2(angle * 14.0, seed)) + 0.18 * vgValueNoise(float2(angle * 33.0, seed + 5.3));
|
|
917
|
+
return edge * atten * clamp(shafts, 0.0, 1.0);
|
|
918
|
+
}
|
|
919
|
+
`;
|
|
695
920
|
var MEDIUM_COMPOSITE_SHADER = `
|
|
696
921
|
uniform shader u_vapor;
|
|
697
922
|
uniform shader u_condensate;
|
|
698
923
|
uniform shader u_track;
|
|
924
|
+
uniform shader u_shadow;
|
|
699
925
|
uniform float2 u_dyeScale;
|
|
700
926
|
uniform float3 u_lab0;
|
|
701
927
|
uniform float3 u_lab1;
|
|
@@ -711,27 +937,68 @@ uniform float u_farBlurRadius;
|
|
|
711
937
|
uniform float u_farWeight;
|
|
712
938
|
uniform float u_gravityBoost;
|
|
713
939
|
uniform float u_gravityBoostStart;
|
|
940
|
+
uniform float3 u_channelScatter;
|
|
941
|
+
uniform float2 u_light0Pos;
|
|
942
|
+
uniform float2 u_light0Dir;
|
|
943
|
+
uniform float u_light0CosCone;
|
|
944
|
+
uniform float u_light0Falloff;
|
|
945
|
+
uniform float3 u_light0Color;
|
|
946
|
+
uniform float u_light0Intensity;
|
|
947
|
+
uniform float2 u_light1Pos;
|
|
948
|
+
uniform float2 u_light1Dir;
|
|
949
|
+
uniform float u_light1CosCone;
|
|
950
|
+
uniform float u_light1Falloff;
|
|
951
|
+
uniform float3 u_light1Color;
|
|
952
|
+
uniform float u_light1Intensity;
|
|
953
|
+
uniform float2 u_light2Pos;
|
|
954
|
+
uniform float2 u_light2Dir;
|
|
955
|
+
uniform float u_light2CosCone;
|
|
956
|
+
uniform float u_light2Falloff;
|
|
957
|
+
uniform float3 u_light2Color;
|
|
958
|
+
uniform float u_light2Intensity;
|
|
959
|
+
uniform float u_trackLightFloor;
|
|
714
960
|
|
|
715
961
|
${VG_OKLAB_TO_SRGB}
|
|
962
|
+
${VG_CUBIC_WEIGHTS}
|
|
963
|
+
${vgBicubicSampler("vgBicubicVapor", "u_vapor")}
|
|
964
|
+
${vgBicubicSampler("vgBicubicCondensate", "u_condensate")}
|
|
965
|
+
${VG_VALUE_NOISE}
|
|
966
|
+
${VG_LIGHT}
|
|
716
967
|
|
|
717
968
|
half4 main(float2 xy) {
|
|
718
969
|
float2 baseSrc = xy * u_dyeScale;
|
|
719
970
|
|
|
720
|
-
// Near plane \u2014
|
|
721
|
-
|
|
722
|
-
half4
|
|
971
|
+
// Near plane \u2014 the calibrated look lives here. Bicubic (see the file header) on vapor and
|
|
972
|
+
// condensate; track stays a plain bilinear read.
|
|
973
|
+
half4 vapor = vgBicubicVapor(baseSrc);
|
|
974
|
+
half4 condensate = vgBicubicCondensate(baseSrc);
|
|
723
975
|
half4 track = u_track.eval(baseSrc);
|
|
724
976
|
|
|
725
|
-
// Far plane \u2014 the identical field, scaled and offset (see the file header).
|
|
726
|
-
//
|
|
727
|
-
//
|
|
977
|
+
// Far plane \u2014 the identical field, scaled and offset (see the file header). An 8-tap ring, not
|
|
978
|
+
// the near plane's \xB1x/\xB1y box: axis-aligned taps read the SAME column/row on both sides of any
|
|
979
|
+
// residual axis-aligned structure (a seam, a resize artifact), which is exactly how a straight
|
|
980
|
+
// line gets doubled into four parallel copies instead of softened away \u2014 measured directly via
|
|
981
|
+
// check-medium.mjs's isotropy gate (see its report). The ring is rotated a half-step (22.5\xB0) off
|
|
982
|
+
// the axes so no tap direction ever coincides with a grid row or column. Radius stays in the same
|
|
983
|
+
// far-plane texture-space unit as before (u_farBlurRadius, grid-px) \u2014 only the tap PATTERN
|
|
984
|
+
// changed, not what it measures in.
|
|
728
985
|
float2 farSrc = baseSrc * u_farScale + u_farOffset;
|
|
729
|
-
float2
|
|
730
|
-
float2
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
986
|
+
float2 ring0 = float2( 0.9238795, 0.3826834) * u_farBlurRadius;
|
|
987
|
+
float2 ring1 = float2( 0.3826834, 0.9238795) * u_farBlurRadius;
|
|
988
|
+
float2 ring2 = float2(-0.3826834, 0.9238795) * u_farBlurRadius;
|
|
989
|
+
float2 ring3 = float2(-0.9238795, 0.3826834) * u_farBlurRadius;
|
|
990
|
+
float2 ring4 = float2(-0.9238795, -0.3826834) * u_farBlurRadius;
|
|
991
|
+
float2 ring5 = float2(-0.3826834, -0.9238795) * u_farBlurRadius;
|
|
992
|
+
float2 ring6 = float2( 0.3826834, -0.9238795) * u_farBlurRadius;
|
|
993
|
+
float2 ring7 = float2( 0.9238795, -0.3826834) * u_farBlurRadius;
|
|
994
|
+
half4 vaporFar = (u_vapor.eval(farSrc + ring0) + u_vapor.eval(farSrc + ring1) +
|
|
995
|
+
u_vapor.eval(farSrc + ring2) + u_vapor.eval(farSrc + ring3) +
|
|
996
|
+
u_vapor.eval(farSrc + ring4) + u_vapor.eval(farSrc + ring5) +
|
|
997
|
+
u_vapor.eval(farSrc + ring6) + u_vapor.eval(farSrc + ring7)) * half4(0.125);
|
|
998
|
+
half4 condensateFar = (u_condensate.eval(farSrc + ring0) + u_condensate.eval(farSrc + ring1) +
|
|
999
|
+
u_condensate.eval(farSrc + ring2) + u_condensate.eval(farSrc + ring3) +
|
|
1000
|
+
u_condensate.eval(farSrc + ring4) + u_condensate.eval(farSrc + ring5) +
|
|
1001
|
+
u_condensate.eval(farSrc + ring6) + u_condensate.eval(farSrc + ring7)) * half4(0.125);
|
|
735
1002
|
|
|
736
1003
|
// Gravity's "denser layer at the bottom of the chamber" \u2014 a compositing-only boost (see
|
|
737
1004
|
// MEDIUM_DEFAULTS.gravityBottomBoost): it scales how density already in the conserved buffers is
|
|
@@ -764,7 +1031,34 @@ half4 main(float2 xy) {
|
|
|
764
1031
|
float total = max(w0 + w1 + w2 + wBg + wCondensate, 1e-4);
|
|
765
1032
|
float3 mixLab =
|
|
766
1033
|
(u_labBg * wBg + u_lab0 * w0 + u_lab1 * w1 + u_lab2 * w2 + condensateLab * wCondensate) / total;
|
|
767
|
-
|
|
1034
|
+
// The dark ambient base \u2014 this is where the OLD mechanism stops (see the file header on
|
|
1035
|
+
// VG_LIGHT): unclamped here, clamped once at the very end, after the lit layer adds in.
|
|
1036
|
+
float3 rgbLinearBase = vgOklabToLinear(mixLab);
|
|
1037
|
+
|
|
1038
|
+
// Spotlights reach this point dimmed by the gas in front of them (shadow-shader.ts).
|
|
1039
|
+
half4 shadow = u_shadow.eval(baseSrc);
|
|
1040
|
+
float light0 = vgLightAmount(xy, u_light0Pos, u_light0Dir, u_light0CosCone, u_light0Falloff, u_resolution, 1.7) * u_light0Intensity;
|
|
1041
|
+
float light1 = vgLightAmount(xy, u_light1Pos, u_light1Dir, u_light1CosCone, u_light1Falloff, u_resolution, 4.1) * u_light1Intensity
|
|
1042
|
+
* float(shadow.r);
|
|
1043
|
+
float light2 = vgLightAmount(xy, u_light2Pos, u_light2Dir, u_light2CosCone, u_light2Falloff, u_resolution, 8.3) * u_light2Intensity
|
|
1044
|
+
* float(shadow.g);
|
|
1045
|
+
float3 illum = u_light0Color * light0 + u_light1Color * light1 + u_light2Color * light2;
|
|
1046
|
+
|
|
1047
|
+
float totalScatter = gasR * u_channelScatter.x + gasG * u_channelScatter.y + gasB * u_channelScatter.z;
|
|
1048
|
+
float fogDensity = totalScatter + wCondensate;
|
|
1049
|
+
float mist = 0.006 + fogDensity * 0.2;
|
|
1050
|
+
|
|
1051
|
+
// TRACKS: lit the same way as the mist, plus a floor so a track already on screen never vanishes
|
|
1052
|
+
// entirely just because it drifted out of a cone (a fresh ionization trail reads brighter than
|
|
1053
|
+
// ambient mist in a real chamber). The floor is added to ITS OWN color, not multiplied into illum:
|
|
1054
|
+
// illum is exactly [0,0,0] in a fully unlit spot (every light's amount is 0 there), so a floor
|
|
1055
|
+
// multiplied by illum would vanish exactly where it exists to help \u2014 it needs a color of its own
|
|
1056
|
+
// (a neutral, self-luminous glow) rather than borrowing whichever light happens to be nearby.
|
|
1057
|
+
float trackDensity = max(float(track.r), max(float(track.g), float(track.b)));
|
|
1058
|
+
float3 trackGlow = (1.0 - exp(-trackDensity * 0.4)) * (illum + float3(u_trackLightFloor)) * 0.08;
|
|
1059
|
+
|
|
1060
|
+
float3 rgbLinear = rgbLinearBase * 0.025 + illum * mist + trackGlow;
|
|
1061
|
+
rgbLinear = float3(1.0) - exp(-rgbLinear * 1.0);
|
|
768
1062
|
float3 srgb = vgLinearToSrgb(rgbLinear);
|
|
769
1063
|
return half4(half3(srgb), half(1.0));
|
|
770
1064
|
}
|
|
@@ -782,7 +1076,6 @@ uniform float u_settle;
|
|
|
782
1076
|
uniform float u_tailDim;
|
|
783
1077
|
uniform float u_intensity;
|
|
784
1078
|
uniform float u_seed;
|
|
785
|
-
uniform float3 u_channelMask;
|
|
786
1079
|
|
|
787
1080
|
${VG_VALUE_NOISE}
|
|
788
1081
|
|
|
@@ -805,20 +1098,46 @@ half4 main(float2 xy) {
|
|
|
805
1098
|
best = max(best, v);
|
|
806
1099
|
}
|
|
807
1100
|
|
|
808
|
-
float3 dye =
|
|
1101
|
+
float3 dye = float3(best * u_intensity);
|
|
809
1102
|
return half4(half3(dye), half(1.0));
|
|
810
1103
|
}
|
|
811
1104
|
`;
|
|
812
1105
|
|
|
1106
|
+
// src/medium/shadow-shader.ts
|
|
1107
|
+
var MEDIUM_SHADOW_SHADER = `
|
|
1108
|
+
uniform shader u_vapor;
|
|
1109
|
+
uniform shader u_condensate;
|
|
1110
|
+
uniform float u_condensateGain;
|
|
1111
|
+
uniform float2 u_light1Grid;
|
|
1112
|
+
uniform float2 u_light2Grid;
|
|
1113
|
+
uniform float u_extinction;
|
|
1114
|
+
|
|
1115
|
+
float vgOpticalDepth(float2 p, float2 lightP) {
|
|
1116
|
+
float2 toLight = lightP - p;
|
|
1117
|
+
float optical = 0.0;
|
|
1118
|
+
for (int i = 1; i <= 24; i++) {
|
|
1119
|
+
float2 q = p + toLight * (float(i) / 24.0);
|
|
1120
|
+
float inside = step(0.0, q.x) * step(q.x, u_resolution.x) * step(0.0, q.y) * step(q.y, u_resolution.y);
|
|
1121
|
+
half4 v = u_vapor.eval(q);
|
|
1122
|
+
half4 c = u_condensate.eval(q);
|
|
1123
|
+
optical += inside * (float(v.r + v.g + v.b) + float(c.r) * u_condensateGain);
|
|
1124
|
+
}
|
|
1125
|
+
return optical * length(toLight) / 24.0 / max(u_resolution.y, 1.0);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
half4 main(float2 xy) {
|
|
1129
|
+
float2 p = float2(xy.x, u_resolution.y - xy.y);
|
|
1130
|
+
float t1 = exp(-vgOpticalDepth(p, u_light1Grid) * u_extinction);
|
|
1131
|
+
float t2 = exp(-vgOpticalDepth(p, u_light2Grid) * u_extinction);
|
|
1132
|
+
return half4(half(t1), half(t2), half(0.0), half(1.0));
|
|
1133
|
+
}
|
|
1134
|
+
`;
|
|
1135
|
+
|
|
813
1136
|
// src/medium/dynamics.ts
|
|
814
1137
|
function hash01(n) {
|
|
815
1138
|
const s = Math.sin(n * 12.9898) * 43758.5453;
|
|
816
1139
|
return s - Math.floor(s);
|
|
817
1140
|
}
|
|
818
|
-
function channelFromSeed(seed) {
|
|
819
|
-
const idx = Math.floor(hash01(seed * 1.37) * 3) % 3;
|
|
820
|
-
return idx === 0 ? [1, 0, 0] : idx === 1 ? [0, 1, 0] : [0, 0, 1];
|
|
821
|
-
}
|
|
822
1141
|
function lerp(range, t) {
|
|
823
1142
|
return range[0] + (range[1] - range[0]) * t;
|
|
824
1143
|
}
|
|
@@ -832,18 +1151,19 @@ function applyTrackDepth(preset, depth) {
|
|
|
832
1151
|
intensity: preset.intensity * intensityScale
|
|
833
1152
|
};
|
|
834
1153
|
}
|
|
835
|
-
function buildEmission(presetName, source, seed, intensityScale) {
|
|
1154
|
+
function buildEmission(presetName, source, seed, intensityScale, angleOverride, lengthScale = 1) {
|
|
836
1155
|
const preset = MEDIUM_TRACK_PRESETS[presetName];
|
|
837
1156
|
const depth = hash01(seed * 4.63);
|
|
838
1157
|
const depthApplied = applyTrackDepth(preset, depth);
|
|
839
1158
|
return {
|
|
840
1159
|
...depthApplied,
|
|
1160
|
+
lengthFrac: depthApplied.lengthFrac * lengthScale,
|
|
841
1161
|
intensity: depthApplied.intensity * intensityScale,
|
|
842
1162
|
source,
|
|
843
|
-
angle: hash01(seed * 7.31) * Math.PI * 2,
|
|
1163
|
+
angle: angleOverride ?? hash01(seed * 7.31) * Math.PI * 2,
|
|
844
1164
|
seed,
|
|
845
|
-
|
|
846
|
-
|
|
1165
|
+
depth,
|
|
1166
|
+
kind: presetName
|
|
847
1167
|
};
|
|
848
1168
|
}
|
|
849
1169
|
function createMediumDynamics() {
|
|
@@ -869,8 +1189,15 @@ function createMediumDynamics() {
|
|
|
869
1189
|
const eligible = hash01(bar * 0.618) < MEDIUM_EMISSION_PROBABILITY && simTime - lastEmissionAt >= MEDIUM_MIN_EMISSION_INTERVAL;
|
|
870
1190
|
if (eligible) {
|
|
871
1191
|
lastEmissionAt = simTime;
|
|
872
|
-
const
|
|
873
|
-
|
|
1192
|
+
const rayCount = Math.round(lerp(MEDIUM_ALPHA_BURST_RAYS, hash01(bar * 9.17)));
|
|
1193
|
+
for (let i = 0; i < rayCount; i += 1) {
|
|
1194
|
+
const raySeed = bar + (i + 1) * 0.0137;
|
|
1195
|
+
const angle = (i + hash01(raySeed * 5.23)) / rayCount * Math.PI * 2;
|
|
1196
|
+
const lengthScale = lerp(MEDIUM_ALPHA_RAY_LENGTH_SCALE, hash01(raySeed * 2.91));
|
|
1197
|
+
emissions.push(
|
|
1198
|
+
buildEmission("alpha", sourcePoint, raySeed, 0.6 + 0.4 * amp, angle, lengthScale)
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
874
1201
|
}
|
|
875
1202
|
}
|
|
876
1203
|
} else if (state === "idle") {
|
|
@@ -882,7 +1209,8 @@ function createMediumDynamics() {
|
|
|
882
1209
|
hash01(idx * 2.1 + 0.5),
|
|
883
1210
|
MEDIUM_SENSITIVE_TOP + hash01(idx * 5.9 + 1.7) * (MEDIUM_SENSITIVE_BOTTOM - MEDIUM_SENSITIVE_TOP)
|
|
884
1211
|
];
|
|
885
|
-
|
|
1212
|
+
const presetName = hash01(idx * 3.14) < 0.5 ? "electron" : "muon";
|
|
1213
|
+
emissions.push(buildEmission(presetName, randomSource, idx, 1));
|
|
886
1214
|
nextNaturalAt = idleClock + MEDIUM_NATURAL_INTERVAL + hash01(idx * 1.7) * MEDIUM_NATURAL_JITTER;
|
|
887
1215
|
}
|
|
888
1216
|
}
|
|
@@ -891,21 +1219,73 @@ function createMediumDynamics() {
|
|
|
891
1219
|
return { step };
|
|
892
1220
|
}
|
|
893
1221
|
|
|
1222
|
+
// src/medium/light-rig.ts
|
|
1223
|
+
var clamp012 = (v) => Math.min(1, Math.max(0, v));
|
|
1224
|
+
var EDGE_STRIP_CONE_ANGLE = Math.PI - 1e-6;
|
|
1225
|
+
var EDGE_STRIP_TINT_MIX = 0.22;
|
|
1226
|
+
var GEL_LIGHTNESS = 0.7;
|
|
1227
|
+
var LIGHT_HUE_SPREAD = MEDIUM_SPECIES_HUE_SPREAD / 2;
|
|
1228
|
+
function retint(base, hueDeg, chroma, mix2) {
|
|
1229
|
+
const [baseL, a, b] = srgbToOklab(base);
|
|
1230
|
+
const l = baseL + (Math.min(baseL, GEL_LIGHTNESS) - baseL) * mix2;
|
|
1231
|
+
const rad = hueDeg * Math.PI / 180;
|
|
1232
|
+
const targetA = chroma * Math.cos(rad);
|
|
1233
|
+
const targetB = chroma * Math.sin(rad);
|
|
1234
|
+
const mixedA = a + (targetA - a) * mix2;
|
|
1235
|
+
const mixedB = b + (targetB - b) * mix2;
|
|
1236
|
+
let lo = 0;
|
|
1237
|
+
let hi = 1;
|
|
1238
|
+
if (inGamut(oklabToSrgb([l, mixedA, mixedB]))) lo = 1;
|
|
1239
|
+
else {
|
|
1240
|
+
for (let i = 0; i < 12; i += 1) {
|
|
1241
|
+
const mid = (lo + hi) / 2;
|
|
1242
|
+
if (inGamut(oklabToSrgb([l, mixedA * mid, mixedB * mid]))) lo = mid;
|
|
1243
|
+
else hi = mid;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
const rgb = oklabToSrgb([l, mixedA * lo, mixedB * lo]).map(clamp012);
|
|
1247
|
+
const gain = Math.max(...base) / Math.max(...rgb, 1e-6);
|
|
1248
|
+
return rgb.map((v) => clamp012(v * gain));
|
|
1249
|
+
}
|
|
1250
|
+
var inGamut = (rgb) => rgb.every((v) => v >= -1e-4 && v <= 1 + 1e-4);
|
|
1251
|
+
function lightRigForCharacter(character, baseLights = MEDIUM_DEFAULT_LIGHTS) {
|
|
1252
|
+
const spotlightIndices = [];
|
|
1253
|
+
baseLights.forEach((light, i) => {
|
|
1254
|
+
if (light.coneAngle < EDGE_STRIP_CONE_ANGLE) spotlightIndices.push(i);
|
|
1255
|
+
});
|
|
1256
|
+
const spotlightCount = spotlightIndices.length;
|
|
1257
|
+
return baseLights.map((light, i) => {
|
|
1258
|
+
if (light.coneAngle >= EDGE_STRIP_CONE_ANGLE) {
|
|
1259
|
+
return { ...light, color: retint(light.color, character.hue, character.chroma, EDGE_STRIP_TINT_MIX) };
|
|
1260
|
+
}
|
|
1261
|
+
const slot = spotlightIndices.indexOf(i);
|
|
1262
|
+
const hueOffset = spotlightCount > 1 ? LIGHT_HUE_SPREAD * (2 * slot / (spotlightCount - 1) - 1) : 0;
|
|
1263
|
+
return { ...light, color: retint(light.color, character.hue + hueOffset, character.chroma, 1) };
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
function lightRigForCover(cover, baseLights = MEDIUM_DEFAULT_LIGHTS) {
|
|
1267
|
+
return lightRigForCharacter(characterOf(cover), baseLights);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
894
1270
|
exports.ATOM_AT_REST = ATOM_AT_REST;
|
|
895
1271
|
exports.DEFAULT_GROWTH_TIMING = DEFAULT_GROWTH_TIMING;
|
|
896
1272
|
exports.LINEAR_TO_LMS = LINEAR_TO_LMS;
|
|
897
1273
|
exports.LMS_TO_LINEAR = LMS_TO_LINEAR;
|
|
898
1274
|
exports.LMS_TO_OKLAB = LMS_TO_OKLAB;
|
|
1275
|
+
exports.MEDIUM_ALPHA_BURST_RAYS = MEDIUM_ALPHA_BURST_RAYS;
|
|
1276
|
+
exports.MEDIUM_ALPHA_RAY_LENGTH_SCALE = MEDIUM_ALPHA_RAY_LENGTH_SCALE;
|
|
899
1277
|
exports.MEDIUM_COMPOSITE_SHADER = MEDIUM_COMPOSITE_SHADER;
|
|
900
1278
|
exports.MEDIUM_CONDENSATE_CORRECT_SHADER = MEDIUM_CONDENSATE_CORRECT_SHADER;
|
|
901
1279
|
exports.MEDIUM_CONDENSATE_FORWARD_SHADER = MEDIUM_CONDENSATE_FORWARD_SHADER;
|
|
902
1280
|
exports.MEDIUM_CONDENSATE_REACT_SHADER = MEDIUM_CONDENSATE_REACT_SHADER;
|
|
903
1281
|
exports.MEDIUM_DEFAULTS = MEDIUM_DEFAULTS;
|
|
904
1282
|
exports.MEDIUM_DEFAULT_CELL_PX = MEDIUM_DEFAULT_CELL_PX;
|
|
1283
|
+
exports.MEDIUM_DEFAULT_LIGHTS = MEDIUM_DEFAULT_LIGHTS;
|
|
905
1284
|
exports.MEDIUM_DRIFT_TURBULENCE = MEDIUM_DRIFT_TURBULENCE;
|
|
906
1285
|
exports.MEDIUM_EMISSION_BEATS = MEDIUM_EMISSION_BEATS;
|
|
907
1286
|
exports.MEDIUM_EMISSION_PROBABILITY = MEDIUM_EMISSION_PROBABILITY;
|
|
908
1287
|
exports.MEDIUM_EMIT_SHADER = MEDIUM_EMIT_SHADER;
|
|
1288
|
+
exports.MEDIUM_MAX_LIGHTS = MEDIUM_MAX_LIGHTS;
|
|
909
1289
|
exports.MEDIUM_MIN_EMISSION_INTERVAL = MEDIUM_MIN_EMISSION_INTERVAL;
|
|
910
1290
|
exports.MEDIUM_NATURAL_INTERVAL = MEDIUM_NATURAL_INTERVAL;
|
|
911
1291
|
exports.MEDIUM_NATURAL_JITTER = MEDIUM_NATURAL_JITTER;
|
|
@@ -915,12 +1295,21 @@ exports.MEDIUM_RESAMPLE_SHADER = MEDIUM_RESAMPLE_SHADER;
|
|
|
915
1295
|
exports.MEDIUM_SEED_SHADER = MEDIUM_SEED_SHADER;
|
|
916
1296
|
exports.MEDIUM_SENSITIVE_BOTTOM = MEDIUM_SENSITIVE_BOTTOM;
|
|
917
1297
|
exports.MEDIUM_SENSITIVE_TOP = MEDIUM_SENSITIVE_TOP;
|
|
1298
|
+
exports.MEDIUM_SHADOW_SHADER = MEDIUM_SHADOW_SHADER;
|
|
918
1299
|
exports.MEDIUM_SPECIES_HUE_SPREAD = MEDIUM_SPECIES_HUE_SPREAD;
|
|
919
1300
|
exports.MEDIUM_SPECIES_LIGHTNESS = MEDIUM_SPECIES_LIGHTNESS;
|
|
920
1301
|
exports.MEDIUM_TIME_PERIOD = MEDIUM_TIME_PERIOD;
|
|
921
1302
|
exports.MEDIUM_TRACK_ADVECT_SHADER = MEDIUM_TRACK_ADVECT_SHADER;
|
|
922
1303
|
exports.MEDIUM_TRACK_DEPTH_INTENSITY_RANGE = MEDIUM_TRACK_DEPTH_INTENSITY_RANGE;
|
|
923
1304
|
exports.MEDIUM_TRACK_DEPTH_WIDTH_RANGE = MEDIUM_TRACK_DEPTH_WIDTH_RANGE;
|
|
1305
|
+
exports.MEDIUM_TRACK_LAYER_BURST_ACCENT = MEDIUM_TRACK_LAYER_BURST_ACCENT;
|
|
1306
|
+
exports.MEDIUM_TRACK_LAYER_BURST_SPREAD = MEDIUM_TRACK_LAYER_BURST_SPREAD;
|
|
1307
|
+
exports.MEDIUM_TRACK_LAYER_CURL_PUSH = MEDIUM_TRACK_LAYER_CURL_PUSH;
|
|
1308
|
+
exports.MEDIUM_TRACK_LAYER_FADE_GAMMA = MEDIUM_TRACK_LAYER_FADE_GAMMA;
|
|
1309
|
+
exports.MEDIUM_TRACK_LAYER_GRAVITY_SAG = MEDIUM_TRACK_LAYER_GRAVITY_SAG;
|
|
1310
|
+
exports.MEDIUM_TRACK_LAYER_LIFE_SECONDS = MEDIUM_TRACK_LAYER_LIFE_SECONDS;
|
|
1311
|
+
exports.MEDIUM_TRACK_LAYER_LOOK = MEDIUM_TRACK_LAYER_LOOK;
|
|
1312
|
+
exports.MEDIUM_TRACK_LAYER_MAX_TRACKS = MEDIUM_TRACK_LAYER_MAX_TRACKS;
|
|
924
1313
|
exports.MEDIUM_TRACK_PRESETS = MEDIUM_TRACK_PRESETS;
|
|
925
1314
|
exports.MEDIUM_TURBULENCE_TAU = MEDIUM_TURBULENCE_TAU;
|
|
926
1315
|
exports.MEDIUM_VAPOR_CORRECT_SHADER = MEDIUM_VAPOR_CORRECT_SHADER;
|
|
@@ -941,6 +1330,8 @@ exports.depthFarOffsetPx = depthFarOffsetPx;
|
|
|
941
1330
|
exports.growthFrame = growthFrame;
|
|
942
1331
|
exports.growthInk = growthInk;
|
|
943
1332
|
exports.growthPhase = growthPhase;
|
|
1333
|
+
exports.lightRigForCharacter = lightRigForCharacter;
|
|
1334
|
+
exports.lightRigForCover = lightRigForCover;
|
|
944
1335
|
exports.neutralSpecies = neutralSpecies;
|
|
945
1336
|
exports.oklabToSrgb = oklabToSrgb;
|
|
946
1337
|
exports.smoothstep = smoothstep;
|