initial remote
This commit is contained in:
@@ -12,6 +12,12 @@ export function sampleBubbles(track, params, rng) {
|
||||
const pts = track.pts;
|
||||
if (pts.length < 2) return bubbles;
|
||||
|
||||
// per-track scales let non-track features (e.g. the shock disk) reuse the
|
||||
// exact same nucleation method with their own density/size/jitter.
|
||||
const dScale = track.densityScale ?? 1;
|
||||
const sScale = track.sizeScale ?? 1;
|
||||
const jitter = track.jitter ?? 0.0016;
|
||||
|
||||
for (let i = 1; i < pts.length; i++) {
|
||||
const a = pts[i - 1], b = pts[i];
|
||||
const dx = b.x - a.x, dy = b.y - a.y;
|
||||
@@ -19,7 +25,7 @@ export function sampleBubbles(track, params, rng) {
|
||||
if (segLen === 0) continue;
|
||||
|
||||
const beta = Math.max(a.beta, 0.13);
|
||||
const lambda = params.density * track.weight * (1 / (beta * beta)) * 420;
|
||||
const lambda = params.density * track.weight * dScale * (1 / (beta * beta)) * 420;
|
||||
const expected = lambda * segLen;
|
||||
const nb = Math.floor(expected) + (rng() < (expected - Math.floor(expected)) ? 1 : 0);
|
||||
|
||||
@@ -28,8 +34,8 @@ export function sampleBubbles(track, params, rng) {
|
||||
const t = rng();
|
||||
const px = a.x + dx * t;
|
||||
const py = a.y + dy * t;
|
||||
const j = gauss(rng) * 0.0016;
|
||||
const baseR = (0.0011 + (1 - beta) * 0.0017) * params.size;
|
||||
const j = gauss(rng) * jitter;
|
||||
const baseR = (0.0011 + (1 - beta) * 0.0017) * params.size * sScale;
|
||||
// occasional fat bubble (clumped nucleation)
|
||||
const fat = rng() < 0.05 ? 1.8 + rng() : 1;
|
||||
const r = baseR * (0.65 + rng() * 0.55) * fat;
|
||||
|
||||
@@ -44,7 +44,7 @@ export function paramsFromSeed(seed) {
|
||||
cosmics: ri(4, 10), sweepers: ri(2, 7),
|
||||
bfield: r(0.8, 1.6), eloss: r(0.45, 0.75), pspread: r(0.6, 0.85),
|
||||
deltaRate: r(0.6, 0.95), deltaTight: r(0.6, 1.0),
|
||||
shock: true, shockIntensity: r(0.6, 0.9), shockSize: r(0.26, 0.4),
|
||||
shock: true, diskBubbles: true, shockIntensity: r(0.6, 0.9), shockSize: r(0.26, 0.4),
|
||||
shockStriations: r(0.45, 0.85), shockY: r(0.4, 0.6), shockX: r(-0.12, 0.12),
|
||||
shockStain: Math.pow(rng(), 1.5), // skew cleaner, allow grime
|
||||
instrument: r(0.25, 0.6),
|
||||
|
||||
@@ -105,5 +105,62 @@ export function generateShock(params, rng) {
|
||||
});
|
||||
}
|
||||
|
||||
return { x, y, r, intensity: I, stain, striations, rimSegs, rings, stains, core, bright: r * 0.12 };
|
||||
const shock = { x, y, r, intensity: I, stain, striations, rimSegs, rings, stains, core, bright: r * 0.12 };
|
||||
// Describe the disk's line work with the SAME bubble-nucleation method as the
|
||||
// particle tracks, so it shares their granular texture instead of reading as
|
||||
// clean vector strokes. Each entry is a track-like polyline for sampleBubbles.
|
||||
shock.bubbleStrokes = buildBubbleStrokes(shock);
|
||||
return shock;
|
||||
}
|
||||
|
||||
const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
|
||||
|
||||
function buildBubbleStrokes(sh) {
|
||||
const { x, y, r } = sh;
|
||||
const out = [];
|
||||
|
||||
// radial striations → short streaks (perpendicular jitter gives them width)
|
||||
for (const s of sh.striations) {
|
||||
out.push({
|
||||
pts: [
|
||||
{ x: x + Math.cos(s.a) * s.inner, y: y + Math.sin(s.a) * s.inner, beta: 0.58 },
|
||||
{ x: x + Math.cos(s.a) * s.outer, y: y + Math.sin(s.a) * s.outer, beta: 0.5 },
|
||||
],
|
||||
weight: clamp(s.opacity * 2.0, 0.35, 0.95),
|
||||
densityScale: 0.22, sizeScale: 0.9, jitter: 0.0045,
|
||||
});
|
||||
}
|
||||
|
||||
// eroded rim segments → dense arcs of bubbles
|
||||
for (const seg of sh.rimSegs) {
|
||||
const steps = Math.max(3, Math.round((seg.a1 - seg.a0) / 0.06));
|
||||
const pts = [];
|
||||
for (let i = 0; i <= steps; i++) {
|
||||
const a = seg.a0 + (seg.a1 - seg.a0) * (i / steps);
|
||||
pts.push({ x: x + Math.cos(a) * r, y: y + Math.sin(a) * r, beta: 0.45 });
|
||||
}
|
||||
out.push({ pts, weight: clamp(seg.opacity * 1.6, 0.4, 0.95), densityScale: 0.34, sizeScale: 1.0, jitter: 0.004 });
|
||||
}
|
||||
|
||||
// concentric pressure-front rings → faint dotted circles
|
||||
for (const ring of sh.rings) {
|
||||
const n = Math.max(40, Math.round(ring.rr * 200));
|
||||
const pts = [];
|
||||
for (let i = 0; i <= n; i++) {
|
||||
const a = (i / n) * Math.PI * 2;
|
||||
pts.push({ x: x + Math.cos(a) * ring.rr, y: y + Math.sin(a) * ring.rr, beta: 0.7 });
|
||||
}
|
||||
out.push({ pts, weight: clamp(ring.opacity * 2.6, 0.3, 0.8), densityScale: 0.12, sizeScale: 0.85, jitter: 0.003 });
|
||||
}
|
||||
|
||||
// textured core cracks → short bubble streaks
|
||||
for (const k of sh.core) {
|
||||
out.push({
|
||||
pts: [{ x: k.x1, y: k.y1, beta: 0.42 }, { x: k.x2, y: k.y2, beta: 0.42 }],
|
||||
weight: clamp(k.opacity * 1.6, 0.35, 0.9),
|
||||
densityScale: 0.3, sizeScale: 0.95, jitter: 0.0045,
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user