Hidden Realities — Milkweed & shared wind field
First plate of the hidden-realities series: natural subjects as instrument photographs. One invisible wind field, three detectors — dunes (time-integrated, what the sand remembers), water (instantaneous), milkweed seeds (advected test particles). - src/field/wind.js: divergence-free curl-noise field with closed-form time integral; displacement / scalar / stepped-vec samplers. - src/scene/umbel.js: milkweed head as a particle interaction vertex; burst releases pedicels to seed. src/scene/drift.js: seeds advected, same track contract as track.js. - composition.js: switch -> GROUP_BUILDERS registry; fieldLake/flora/ drift layers + wind plumbing. carpet.js/perspgrid.js: warpFn/phaseFn/ modesFn/heightFn injection hooks (default off, no regression). - schema + composer panels, dunelake ink palette, dune-lake template, tools/dunelake.mjs (17-plate matrix) and its curated SVG set. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
240
output/dunelake/criticaldune-breeze_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big water, high dune line (CRITICALDUNE-7) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/criticaldune-breeze_high-water.svg
Normal file
|
After Width: | Height: | Size: 10 MiB |
240
output/dunelake/criticaldune-breeze_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big sky, dunes low (CRITICALDUNE-7) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/criticaldune-breeze_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |
240
output/dunelake/criticaldune-gale_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big water, high dune line (CRITICALDUNE-7) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/criticaldune-gale_high-water.svg
Normal file
|
After Width: | Height: | Size: 8.6 MiB |
240
output/dunelake/criticaldune-gale_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big sky, dunes low (CRITICALDUNE-7) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/criticaldune-gale_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 9.0 MiB |
240
output/dunelake/lakemich-breeze_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big water, high dune line (LAKEMICH-0610) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/lakemich-breeze_high-water.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |
240
output/dunelake/lakemich-breeze_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big sky, dunes low (LAKEMICH-0610) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/lakemich-breeze_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |
240
output/dunelake/lakemich-gale_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big water, high dune line (LAKEMICH-0610) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/lakemich-gale_high-water.svg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
240
output/dunelake/lakemich-gale_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big sky, dunes low (LAKEMICH-0610) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/lakemich-gale_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 9.4 MiB |
5
output/dunelake/matrix.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Dunes on a Great Lake — one wind, three detectors</title>
|
||||
<style>html,body{margin:0;background:#15140f;color:#cabfa6;font:12px ui-monospace,monospace}h1{font-weight:400;letter-spacing:.2em;text-transform:uppercase;color:#9fb7af;padding:18px 14px 0}p.sub{color:#8a8068;padding:0 14px;margin:6px 0 0}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;padding:14px}figure{margin:0;position:relative;background:#fff;overflow:hidden}img{width:100%;display:block}figcaption{position:absolute;left:0;bottom:0;right:0;padding:6px 9px;font:12px ui-monospace,monospace;color:#fff;background:linear-gradient(transparent,#000d)}</style></head><body>
|
||||
<h1>Dunes on a Great Lake with Milkweed (17)</h1>
|
||||
<p class="sub">one invisible wind field · three detectors — sand (integrated) · water (instantaneous) · seeds (advected)</p>
|
||||
<div class="grid"><figure><img src="lakemich-breeze_low-horizon.svg"><figcaption>breeze · big sky, dunes low (LAKEMICH-0610)</figcaption></figure><figure><img src="lakemich-breeze_high-water.svg"><figcaption>breeze · big water, high dune line (LAKEMICH-0610)</figcaption></figure><figure><img src="lakemich-gale_low-horizon.svg"><figcaption>gale · big sky, dunes low (LAKEMICH-0610)</figcaption></figure><figure><img src="lakemich-gale_high-water.svg"><figcaption>gale · big water, high dune line (LAKEMICH-0610)</figcaption></figure><figure><img src="sleeping-breeze_low-horizon.svg"><figcaption>breeze · big sky, dunes low (SLEEPING-BEAR-22)</figcaption></figure><figure><img src="sleeping-breeze_high-water.svg"><figcaption>breeze · big water, high dune line (SLEEPING-BEAR-22)</figcaption></figure><figure><img src="sleeping-gale_low-horizon.svg"><figcaption>gale · big sky, dunes low (SLEEPING-BEAR-22)</figcaption></figure><figure><img src="sleeping-gale_high-water.svg"><figcaption>gale · big water, high dune line (SLEEPING-BEAR-22)</figcaption></figure><figure><img src="criticaldune-breeze_low-horizon.svg"><figcaption>breeze · big sky, dunes low (CRITICALDUNE-7)</figcaption></figure><figure><img src="criticaldune-breeze_high-water.svg"><figcaption>breeze · big water, high dune line (CRITICALDUNE-7)</figcaption></figure><figure><img src="criticaldune-gale_low-horizon.svg"><figcaption>gale · big sky, dunes low (CRITICALDUNE-7)</figcaption></figure><figure><img src="criticaldune-gale_high-water.svg"><figcaption>gale · big water, high dune line (CRITICALDUNE-7)</figcaption></figure><figure><img src="states_closed-left.svg"><figcaption>umbels closed — the vertex before the decay</figcaption></figure><figure><img src="states_bursting-right.svg"><figcaption>right-third bursting — half the florets gone to silk</figcaption></figure><figure><img src="states_full-release.svg"><figcaption>off-corner full burst — seeds streaming across the water</figcaption></figure><figure><img src="palette_dusk.svg"><figcaption>dusk — sand holds the late light, slate water</figcaption></figure><figure><img src="palette_nocturne.svg"><figcaption>nocturne — dark plate, pale silks (night-plate move)</figcaption></figure></div></body></html>
|
||||
240
output/dunelake/palette_dusk.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · dusk — sand holds the late light, slate water */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.8,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(210,190,170)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.5,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.62,
|
||||
"hueFront": 0.58,
|
||||
"sat": 0.5,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.39,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.35000000000000003,
|
||||
1,
|
||||
0.5700000000000001
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.05,
|
||||
"hueFront": 0.95,
|
||||
"sat": 0.5,
|
||||
"light": 0.4
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.55,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/palette_dusk.svg
Normal file
|
After Width: | Height: | Size: 9.3 MiB |
240
output/dunelake/palette_nocturne.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · nocturne — dark plate, pale silks (night-plate move) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "CRITICALDUNE-7",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.1,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(22,23,30)",
|
||||
"film": {
|
||||
"opacity": 0.28,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.3,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.3,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.2,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.58,
|
||||
"hueFront": 0.56,
|
||||
"sat": 0.4,
|
||||
"light": 0.66
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.39,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.35000000000000003,
|
||||
1,
|
||||
0.5700000000000001
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-CRITICALDUNE-7",
|
||||
"color": {
|
||||
"hueBack": 0.6,
|
||||
"hueFront": 0.08,
|
||||
"sat": 0.3,
|
||||
"light": 0.62
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.55,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.6,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-CRITICALDUNE-7"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 48,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#cfc4a8",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/palette_nocturne.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |
240
output/dunelake/sleeping-breeze_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big water, high dune line (SLEEPING-BEAR-22) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "SLEEPING-BEAR-22",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-SLEEPING-BEAR-22"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/sleeping-breeze_high-water.svg
Normal file
|
After Width: | Height: | Size: 9.4 MiB |
240
output/dunelake/sleeping-breeze_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · breeze · big sky, dunes low (SLEEPING-BEAR-22) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "SLEEPING-BEAR-22",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-SLEEPING-BEAR-22"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/sleeping-breeze_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 9.7 MiB |
240
output/dunelake/sleeping-gale_high-water.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big water, high dune line (SLEEPING-BEAR-22) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "SLEEPING-BEAR-22",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.28,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.24,
|
||||
1,
|
||||
0.46
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.44,
|
||||
"lines": 44,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.3,
|
||||
"y": 0.5,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-SLEEPING-BEAR-22"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.3,
|
||||
0.5
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/sleeping-gale_high-water.svg
Normal file
|
After Width: | Height: | Size: 7.9 MiB |
240
output/dunelake/sleeping-gale_low-horizon.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · gale · big sky, dunes low (SLEEPING-BEAR-22) */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "SLEEPING-BEAR-22",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.45999999999999996,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.42,
|
||||
1,
|
||||
0.64
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.62,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.34,
|
||||
"y": 0.42,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.25,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-SLEEPING-BEAR-22"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "wind · integrated | instantaneous | advected",
|
||||
"target": [
|
||||
-0.34,
|
||||
0.42
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/sleeping-gale_low-horizon.svg
Normal file
|
After Width: | Height: | Size: 8.4 MiB |
240
output/dunelake/states_bursting-right.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · right-third bursting — half the florets gone to silk */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.25,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.4,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.36000000000000004,
|
||||
1,
|
||||
0.5800000000000001
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.56,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.42,
|
||||
"y": 0.44,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 3,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0.55,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 40,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "release fraction 0.55",
|
||||
"target": [
|
||||
0.42,
|
||||
0.44
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/states_bursting-right.svg
Normal file
|
After Width: | Height: | Size: 8.0 MiB |
240
output/dunelake/states_closed-left.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · umbels closed — the vertex before the decay */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "LAKEMICH-0610",
|
||||
"wind": {
|
||||
"seed": "ZEPHYR-011",
|
||||
"strength": 0.55,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.4,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.36000000000000004,
|
||||
1,
|
||||
0.5800000000000001
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-LAKEMICH-0610",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.56,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.5,
|
||||
"y": 0.38,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 2,
|
||||
"scale": 0.42,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 0,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-LAKEMICH-0610"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 28,
|
||||
"slip": 0.4,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "pre-release · all florets held",
|
||||
"target": [
|
||||
-0.5,
|
||||
0.38
|
||||
],
|
||||
"from": [
|
||||
0.35,
|
||||
-0.3
|
||||
]
|
||||
}
|
||||
};
|
||||
16
output/dunelake/states_closed-left.svg
Normal file
|
After Width: | Height: | Size: 4.7 MiB |
240
output/dunelake/states_full-release.mjs
Normal file
@@ -0,0 +1,240 @@
|
||||
/* dune-lake-milkweed · off-corner full burst — seeds streaming across the water */
|
||||
export const composition = {
|
||||
"size": 1600,
|
||||
"seed": "SLEEPING-BEAR-22",
|
||||
"wind": {
|
||||
"seed": "BOREAS-104",
|
||||
"strength": 1.4,
|
||||
"scale": 1.6,
|
||||
"gust": 0.4,
|
||||
"time": 1.4
|
||||
},
|
||||
"background": {
|
||||
"color": "rgb(226,216,192)",
|
||||
"film": {
|
||||
"opacity": 0.5,
|
||||
"density": 0.5,
|
||||
"seed": 8
|
||||
},
|
||||
"aging": {
|
||||
"opacity": 0.35,
|
||||
"scratches": 3,
|
||||
"dust": 0.45,
|
||||
"foxing": 0.5,
|
||||
"seed": 5
|
||||
},
|
||||
"grain": {
|
||||
"opacity": 0.38,
|
||||
"intensity": 0.42,
|
||||
"seed": 19
|
||||
},
|
||||
"glow": {
|
||||
"strength": 0.4,
|
||||
"followSun": false
|
||||
},
|
||||
"vignette": {
|
||||
"strength": 0.32,
|
||||
"mode": "radial",
|
||||
"cx": 0.5,
|
||||
"cy": 0.42,
|
||||
"radius": 0.9,
|
||||
"angle": 90,
|
||||
"start": 0.5
|
||||
}
|
||||
},
|
||||
"fieldLake": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "LIMNOS-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.555,
|
||||
"hueFront": 0.52,
|
||||
"sat": 0.42,
|
||||
"light": 0.52
|
||||
},
|
||||
"layers": 2,
|
||||
"chaos": 0.1,
|
||||
"blips": 0.2,
|
||||
"mound": 0,
|
||||
"horizonY": 0.33999999999999997,
|
||||
"lines": 24,
|
||||
"wind": {
|
||||
"warp": 0.55
|
||||
},
|
||||
"clip": [
|
||||
0,
|
||||
0.3,
|
||||
1,
|
||||
0.52
|
||||
]
|
||||
},
|
||||
"fieldSea": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"seed": "AEOLIAN-SLEEPING-BEAR-22",
|
||||
"color": {
|
||||
"hueBack": 0.09,
|
||||
"hueFront": 0.07,
|
||||
"sat": 0.42,
|
||||
"light": 0.42
|
||||
},
|
||||
"layers": 3,
|
||||
"chaos": 0.22,
|
||||
"blips": 0.35,
|
||||
"mound": 0.55,
|
||||
"horizonY": 0.5,
|
||||
"lines": 52,
|
||||
"wind": {
|
||||
"warp": 0.9
|
||||
}
|
||||
},
|
||||
"fieldGrid": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"pos": "over",
|
||||
"style": "floor",
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"color": {
|
||||
"hue": 0.5,
|
||||
"hue2": 0.55,
|
||||
"sat": 0.32,
|
||||
"lightNear": 0.34,
|
||||
"lightFar": 0.62
|
||||
},
|
||||
"opacity": 0.44,
|
||||
"pitch": 0.45,
|
||||
"yaw": 0.42,
|
||||
"persp": 1.1,
|
||||
"dist": 2.8,
|
||||
"nx": 16,
|
||||
"nz": 24,
|
||||
"originY": 0.34,
|
||||
"ripple": {
|
||||
"amp": 0,
|
||||
"freqI": 0.5,
|
||||
"freqK": 0.35,
|
||||
"phase": 0
|
||||
},
|
||||
"resonance": {
|
||||
"amp": 0,
|
||||
"q": 14,
|
||||
"axis": "ties",
|
||||
"hue": 0.06,
|
||||
"sat": 0.7,
|
||||
"light": 0.45
|
||||
},
|
||||
"wind": {
|
||||
"ripple": 0
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0,
|
||||
"y": -0.26,
|
||||
"rotation": 0,
|
||||
"scale": 0.78
|
||||
},
|
||||
"hue": 0.06,
|
||||
"sat": 0.82,
|
||||
"size": 0.16,
|
||||
"pressure": 0.85,
|
||||
"intensity": 0.85,
|
||||
"striations": 0.6,
|
||||
"stain": 0.35,
|
||||
"soften": 1.35
|
||||
},
|
||||
"bubble": {
|
||||
"enabled": false,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": 0.28,
|
||||
"y": -0.1,
|
||||
"rotation": 10,
|
||||
"scale": 0.78
|
||||
},
|
||||
"palette": "magentarise",
|
||||
"saturation": 1.05,
|
||||
"traceHue": 0,
|
||||
"transparentBase": true,
|
||||
"primaries": 18,
|
||||
"sweepers": 5,
|
||||
"cosmics": 6,
|
||||
"eloss": 0.34,
|
||||
"bfield": 1,
|
||||
"deltaRate": 0.6,
|
||||
"showBoundary": true,
|
||||
"boundaryR": 0.45,
|
||||
"boundaryY": 0.35,
|
||||
"boundaryOpacity": 0.4,
|
||||
"instrument": 0.35
|
||||
},
|
||||
"flora": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"transform": {
|
||||
"x": -0.78,
|
||||
"y": 0.62,
|
||||
"rotation": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"palette": "dunelake",
|
||||
"saturation": 1.05,
|
||||
"count": 2,
|
||||
"scale": 0.5,
|
||||
"pedicels": 46,
|
||||
"droop": 0.4,
|
||||
"spread": 1,
|
||||
"burst": 1,
|
||||
"floretSize": 1,
|
||||
"clusterW": 0.7,
|
||||
"clusterH": 0.3,
|
||||
"seed": "ASCLEPIAS-SLEEPING-BEAR-22"
|
||||
},
|
||||
"drift": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"palette": "dunelake",
|
||||
"count": 64,
|
||||
"slip": 0.5,
|
||||
"flutter": 0.55,
|
||||
"settle": 0.06,
|
||||
"tuft": 2
|
||||
},
|
||||
"fiduciaries": {
|
||||
"enabled": true,
|
||||
"layerOpacity": 1,
|
||||
"label": "ASCLEPIAS SYRIACA",
|
||||
"pencil": "#39312a",
|
||||
"width": 1,
|
||||
"arrow": true,
|
||||
"corners": false,
|
||||
"caption": "all silk · the field made visible",
|
||||
"target": [
|
||||
-0.78,
|
||||
0.62
|
||||
],
|
||||
"from": [
|
||||
0.4,
|
||||
-0.35
|
||||
]
|
||||
}
|
||||
};
|
||||
17
output/dunelake/states_full-release.svg
Normal file
|
After Width: | Height: | Size: 14 MiB |
@@ -6,18 +6,30 @@
|
||||
scale about that centre). Groups:
|
||||
|
||||
background — base colour + film/diffusion + aging + grain
|
||||
fieldLake — Field 0: a second carpet band (water — instantaneous wind)
|
||||
fieldSea — Field 1: the ridgeline vacuum carpet (N plate sheets)
|
||||
fieldGrid — Field 2: the rippled perspective depth grid (2 sheets)
|
||||
disk — the shock disk / "sun" (own centre/rotation/scale)
|
||||
bubble — the particle event / tracks (own centre/rotation/scale)
|
||||
flora — milkweed umbels (particle-vertex flower heads)
|
||||
drift — released seeds advected by the shared wind field
|
||||
fiduciaries — frame-level "No 001" + arrow (does NOT scale w/ event)
|
||||
|
||||
comp.wind = { seed, strength, scale, drift, gust, time } defines ONE
|
||||
shared wind field; fieldSea warps by its time-integral (dune memory),
|
||||
fieldLake/fieldGrid ripple by its instantaneous value, and drift
|
||||
advects seeds through it — three detectors of the same invisible field.
|
||||
|
||||
renderComposition(comp, size) → one composited SVG string.
|
||||
============================================================ */
|
||||
import { carpetSVG } from '../qft/carpet.js';
|
||||
import { perspectiveGridSVG, perspFloorSVG } from '../qft/perspgrid.js';
|
||||
import { fiduciarySVG } from './fiduciary.js';
|
||||
import { generateScene } from '../scene/scene.js';
|
||||
import { generateUmbel } from '../scene/umbel.js';
|
||||
import { generateDrift } from '../scene/drift.js';
|
||||
import { makeWindField } from '../field/wind.js';
|
||||
import { makeRng, range } from '../rng.js';
|
||||
import { renderSVG } from '../render/svgVector.js';
|
||||
import { paramsFromSeed } from '../scene/params.js';
|
||||
import { GROUPS, TOGGLES, FIXED } from '../ui/controls.js';
|
||||
@@ -128,6 +140,65 @@ function bubbleLayer(W, seed, b) {
|
||||
return renderSVG(generateScene(p), p, W);
|
||||
}
|
||||
|
||||
// ---------- wind / flora / drift ----------
|
||||
// ONE wind field per composition (seeded independently of the scene so the
|
||||
// weather can be re-rolled without reshuffling the flora).
|
||||
const windFor = (comp, seed) => makeWindField((comp.wind && comp.wind.seed) || seed, comp.wind || {});
|
||||
|
||||
/* Generate the flora's umbels — tracks for the flora layer, release points for
|
||||
the drift layer. Both builders call this with identical inputs, so they agree
|
||||
exactly on which pedicels have gone to seed (no cross-group state). */
|
||||
function floraData(seed, f) {
|
||||
const rng = makeRng(String(f.seed || seed), 'umbel');
|
||||
const defs = f.umbels || Array.from({ length: f.count ?? 1 }, () => ({
|
||||
x: range(rng, -0.5, 0.5) * (f.clusterW ?? 0.9),
|
||||
y: range(rng, -0.5, 0.5) * (f.clusterH ?? 0.5),
|
||||
scale: (f.scale ?? 0.5) * range(rng, 0.8, 1.2),
|
||||
}));
|
||||
const tracks = [], seeds = [];
|
||||
for (const d of defs) {
|
||||
const u = generateUmbel({
|
||||
pedicels: f.pedicels ?? 48, droop: f.droop ?? 0.35, spread: f.spread ?? 1,
|
||||
burst: f.burst ?? 0, floretSize: f.floretSize ?? 1, scale: f.scale ?? 0.5, ...d,
|
||||
}, rng);
|
||||
tracks.push(...u.tracks); seeds.push(...u.seeds);
|
||||
}
|
||||
return { tracks, seeds };
|
||||
}
|
||||
function floraParams(seed, cfg) {
|
||||
const p = bcParamsBase(seed);
|
||||
Object.assign(p, {
|
||||
palette: cfg.palette ?? 'dunelake', saturation: cfg.saturation ?? 1.05, traceHue: cfg.traceHue ?? 0,
|
||||
showBoundary: false, instrument: 0, emit: ['bubble'],
|
||||
});
|
||||
return p;
|
||||
}
|
||||
function floraLayer(W, seed, f) {
|
||||
const { tracks } = floraData(seed, f);
|
||||
return renderSVG({ tracks }, floraParams(seed, f), W);
|
||||
}
|
||||
function driftLayer(W, seed, comp) {
|
||||
const dcfg = comp.drift, f = comp.flora || {};
|
||||
const { seeds } = floraData(seed, f);
|
||||
if (!seeds.length) return null;
|
||||
// seeds are born in the flora layer's LOCAL frame; carry them through the
|
||||
// flora transform so they ride ONE frame-wide wind (the drift layer itself
|
||||
// composites untransformed — the whole point of the shared field)
|
||||
const t = f.transform || {};
|
||||
const rot = (t.rotation ?? 0) * Math.PI / 180, sc = t.scale ?? 1;
|
||||
const cr = Math.cos(rot), sr = Math.sin(rot);
|
||||
const fSeeds = seeds.map((s) => ({
|
||||
x: (s.x * cr - s.y * sr) * sc + (t.x ?? 0),
|
||||
y: (s.x * sr + s.y * cr) * sc + (t.y ?? 0),
|
||||
theta: s.theta + rot,
|
||||
}));
|
||||
const wind = windFor(comp, seed);
|
||||
const rng = makeRng(String(dcfg.seed || f.seed || seed), 'drift');
|
||||
const tracks = generateDrift(dcfg, wind, fSeeds, rng);
|
||||
if (!tracks.length) return null;
|
||||
return renderSVG({ tracks }, floraParams(seed, { palette: dcfg.palette ?? f.palette, saturation: dcfg.saturation ?? f.saturation }), W);
|
||||
}
|
||||
|
||||
// ---------- field decks ----------
|
||||
function seaSheets(W, f) {
|
||||
const n = f.layers ?? 3;
|
||||
@@ -137,8 +208,9 @@ function seaSheets(W, f) {
|
||||
const lightNear = lite != null ? lite : 0.33;
|
||||
const lightFar = lite != null ? Math.min(0.97, lite + 0.18) : 0.56;
|
||||
const base = {
|
||||
mode: 'plate', rows: f.lines ?? 46, horizon: f.horizonY ?? 0.36, wFar: 0.58, wNear: 0.7,
|
||||
mode: 'plate', rows: f.lines ?? 46, horizon: f.horizonY ?? 0.36, wFar: f.wFar ?? 0.58, wNear: f.wNear ?? 0.7,
|
||||
overlap: f.overlap ?? 1.7, mound: f.mound ?? 0.3, sat: (f.color?.sat) ?? 0.6, lightNear, lightFar, blips: f.blips ?? 0.7,
|
||||
warpFn: f.warpFn ?? null, phaseFn: f.phaseFn ?? null, modesFn: f.modesFn ?? null,
|
||||
};
|
||||
const hueBack = f.color?.hueBack ?? 0.54, hueFront = f.color?.hueFront ?? 0.47;
|
||||
const strokes = [{ near: 2.6, far: 1.0 }, { near: 1.6, far: 0.6 }, { near: 1.0, far: 0.38 }];
|
||||
@@ -180,7 +252,8 @@ function gridSheets(W, f) {
|
||||
mode: 'plate', nx: f.nx ?? 16, nz: f.nz ?? 24,
|
||||
pitch: f.pitch ?? 28 * D, yaw: f.yaw ?? 0, roll: f.roll ?? 0, persp: f.persp ?? 1.0,
|
||||
dist: f.dist ?? 3.0, zShift: f.zShift ?? 0, scale: f.scale ?? 1, originX: f.originX ?? 0, originY: f.originY ?? 0.34,
|
||||
rippleAmp: f.ripple?.amp ?? 0, rippleFreqI: f.ripple?.freqI ?? 0.5, rippleFreqK: f.ripple?.freqK ?? 0.35, ripplePhase: f.ripple?.phase ?? 0, ...color,
|
||||
rippleAmp: f.ripple?.amp ?? 0, rippleFreqI: f.ripple?.freqI ?? 0.5, rippleFreqK: f.ripple?.freqK ?? 0.35, ripplePhase: f.ripple?.phase ?? 0,
|
||||
heightFn: f.heightFn ?? null, ...color,
|
||||
};
|
||||
const r = f.resonance || {};
|
||||
const res = { resAmp: r.amp ?? 0, resQ: r.q ?? 14, resAxis: r.axis ?? 'ties', resHue: r.hue ?? 0.06, resSat: r.sat ?? 0.7, resLight: r.light ?? 0.45 };
|
||||
@@ -189,8 +262,93 @@ function gridSheets(W, f) {
|
||||
return [{ href: uri(back), blur: blur[0] ?? 1.1, opacity: op }, { href: uri(front), blur: blur[1] ?? 0, opacity: op + 0.16 }];
|
||||
}
|
||||
|
||||
// The 6 craft groups, in conceptual order.
|
||||
export const COMPOSITION_GROUPS = ['background', 'fieldSea', 'fieldGrid', 'disk', 'bubble', 'fiduciaries'];
|
||||
/* Attach wind closures to a carpet group config. mode 'integrated' = the
|
||||
field's time integral (dune memory) · 'instant' = its live value (water). */
|
||||
function windCarpet(comp, seed, f, mode) {
|
||||
const wcfg = f.wind || {};
|
||||
const warpK = wcfg.warp ?? 0, phaseK = wcfg.phase ?? 0;
|
||||
if ((!warpK && !phaseK) || !comp.wind) return f;
|
||||
const wind = windFor(comp, seed);
|
||||
const T = comp.wind.time ?? 1;
|
||||
const yTop = (f.horizonY ?? 0.36) * 2 - 1; // rows live horizon→bottom
|
||||
const m = wcfg.mode || mode;
|
||||
const warpFn = warpK ? (t, d) => {
|
||||
const x = t * 2 - 1, y = yTop + d * (1 - yTop); // row sample in frame coords
|
||||
return m === 'instant'
|
||||
? warpK * wind.scalar(x, y, T)
|
||||
: warpK * wind.displacement(x, y, T).dy; // what the sand remembers
|
||||
} : null;
|
||||
const phaseFn = phaseK ? (t, r) => phaseK * wind.scalar(t * 2 - 1, r * 0.04, T) : null;
|
||||
return { ...f, warpFn, phaseFn };
|
||||
}
|
||||
|
||||
/* The craft groups as a REGISTRY, in conceptual order. Each builder receives
|
||||
(comp, W, push, seed) and pushes z-ordered pieces. Adding a new layer kind
|
||||
(the next discovery plate) = adding one entry here + a schema default. */
|
||||
const GROUP_BUILDERS = {
|
||||
background(comp, W, push) {
|
||||
const b = comp.background || {};
|
||||
const rgb = parseRGB(b.color);
|
||||
push(0, { rect: b.color || 'rgb(229,222,203)' });
|
||||
if (b.glow && b.glow.strength) {
|
||||
// glow centre follows the sun (disk) unless followSun:false
|
||||
const dt = comp.disk?.transform || {};
|
||||
const fs = b.glow.followSun !== false && comp.disk?.enabled !== false;
|
||||
const gcx = fs ? (((dt.x ?? 0) + 1) / 2) : 0.5, gcy = fs ? (((dt.y ?? 0) + 1) / 2) : 0.44;
|
||||
push(0.6, { href: uri(glowSVG(W, rgb, b.glow.strength, gcx, gcy)), opacity: 1 });
|
||||
}
|
||||
if (b.film && b.film.opacity !== 0) push(1, { href: uri(filmSVG(W, b.film)), opacity: b.film.opacity ?? 0.6 });
|
||||
if (b.vignette && b.vignette.strength) push(90, { href: uri(vignetteSVG(W, b.vignette)), opacity: 1, blend: 'multiply' }); // edge darkening (over the piece)
|
||||
if (b.aging && b.aging.opacity !== 0) push(80, { href: uri(agingSVG(W, b.aging)), opacity: b.aging.opacity ?? 0.55, blend: 'multiply' });
|
||||
if (b.grain && b.grain.opacity !== 0) push(95, { href: uri(grainSVG(W, { seed: b.grain.seed, tone: b.grain.tone, intensity: b.grain.intensity })), opacity: b.grain.opacity ?? 0.42, blend: 'multiply' });
|
||||
},
|
||||
fieldLake(comp, W, push, seed) {
|
||||
const f = comp.fieldLake; if (!f || f.enabled === false) return;
|
||||
seaSheets(W, windCarpet(comp, seed, f, 'instant')).forEach((s, i) => push(7 + i, { href: s.href, blur: s.blur, opacity: s.opacity, transform: f.transform, clip: f.clip }));
|
||||
},
|
||||
fieldSea(comp, W, push, seed) {
|
||||
const f = comp.fieldSea; if (!f || f.enabled === false) return;
|
||||
seaSheets(W, windCarpet(comp, seed, f, 'integrated')).forEach((s, i) => push(10 + i, { href: s.href, blur: s.blur, opacity: s.opacity, transform: f.transform, clip: f.clip }));
|
||||
},
|
||||
fieldGrid(comp, W, push, seed) {
|
||||
let f = comp.fieldGrid; if (!f || f.enabled === false) return;
|
||||
const rip = f.wind?.ripple ?? 0;
|
||||
if (rip && comp.wind) {
|
||||
const wind = windFor(comp, seed);
|
||||
const T = comp.wind.time ?? 1, nx = f.nx ?? 16, nz = f.nz ?? 24;
|
||||
f = { ...f, heightFn: (i, k) => rip * wind.scalar(i / nx, k / nz, T) };
|
||||
}
|
||||
const z0 = f.pos === 'behind' ? 5 : 25;
|
||||
gridSheets(W, f).forEach((s, i) => push(z0 + i, { href: s.href, blur: s.blur, opacity: s.opacity, transform: f.transform, clip: f.clip }));
|
||||
},
|
||||
disk(comp, W, push, seed) {
|
||||
const d = comp.disk; if (!d || d.enabled === false) return;
|
||||
push(40, { href: uri(diskLayer(W, seed, d)), opacity: d.opacity ?? 1, transform: d.transform });
|
||||
},
|
||||
bubble(comp, W, push, seed) {
|
||||
const b = comp.bubble; if (!b || b.enabled === false) return;
|
||||
// transparentBase (default true): float as an object (normal blend). When
|
||||
// false, the event keeps its paper base and composites via multiply.
|
||||
const tb = b.transparentBase !== false;
|
||||
push(50, { href: uri(bubbleLayer(W, seed, b)), opacity: b.opacity ?? 1, transform: b.transform, blend: tb ? undefined : 'multiply' });
|
||||
},
|
||||
flora(comp, W, push, seed) {
|
||||
const f = comp.flora; if (!f || f.enabled === false) return;
|
||||
push(55, { href: uri(floraLayer(W, seed, f)), opacity: f.opacity ?? 1, transform: f.transform, clip: f.clip });
|
||||
},
|
||||
drift(comp, W, push, seed) {
|
||||
const d = comp.drift; if (!d || d.enabled === false) return;
|
||||
const svg = driftLayer(W, seed, comp);
|
||||
if (svg) push(60, { href: uri(svg), opacity: d.opacity ?? 1, transform: d.transform, clip: d.clip });
|
||||
},
|
||||
fiduciaries(comp, W, push, seed) {
|
||||
const fd = comp.fiduciaries; if (!fd || fd.enabled === false) return;
|
||||
const target = fd.target || [comp.bubble?.transform?.x ?? 0, comp.bubble?.transform?.y ?? 0];
|
||||
push(85, { href: uri(fiduciarySVG(W, { ...fd, target, seed })), opacity: 1, transform: fd.transform });
|
||||
},
|
||||
};
|
||||
|
||||
export const COMPOSITION_GROUPS = Object.keys(GROUP_BUILDERS);
|
||||
|
||||
/* Render ONE group to a set of draw "pieces" (z-ordered). The UI caches these
|
||||
per group so editing one layer only re-renders that layer. Each piece:
|
||||
@@ -199,55 +357,8 @@ export function buildGroupPieces(group, comp, W) {
|
||||
const seed = comp.seed || 'MESON-5113';
|
||||
const out = [];
|
||||
const push = (z, o) => out.push({ z, ...o });
|
||||
switch (group) {
|
||||
case 'background': {
|
||||
const b = comp.background || {};
|
||||
const rgb = parseRGB(b.color);
|
||||
push(0, { rect: b.color || 'rgb(229,222,203)' });
|
||||
if (b.glow && b.glow.strength) {
|
||||
// glow centre follows the sun (disk) unless followSun:false
|
||||
const dt = comp.disk?.transform || {};
|
||||
const fs = b.glow.followSun !== false && comp.disk?.enabled !== false;
|
||||
const gcx = fs ? (((dt.x ?? 0) + 1) / 2) : 0.5, gcy = fs ? (((dt.y ?? 0) + 1) / 2) : 0.44;
|
||||
push(0.6, { href: uri(glowSVG(W, rgb, b.glow.strength, gcx, gcy)), opacity: 1 });
|
||||
}
|
||||
if (b.film && b.film.opacity !== 0) push(1, { href: uri(filmSVG(W, b.film)), opacity: b.film.opacity ?? 0.6 });
|
||||
if (b.vignette && b.vignette.strength) push(90, { href: uri(vignetteSVG(W, b.vignette)), opacity: 1, blend: 'multiply' }); // edge darkening (over the piece)
|
||||
if (b.aging && b.aging.opacity !== 0) push(80, { href: uri(agingSVG(W, b.aging)), opacity: b.aging.opacity ?? 0.55, blend: 'multiply' });
|
||||
if (b.grain && b.grain.opacity !== 0) push(95, { href: uri(grainSVG(W, { seed: b.grain.seed, tone: b.grain.tone, intensity: b.grain.intensity })), opacity: b.grain.opacity ?? 0.42, blend: 'multiply' });
|
||||
break;
|
||||
}
|
||||
case 'fieldSea': {
|
||||
const f = comp.fieldSea; if (!f || f.enabled === false) break;
|
||||
seaSheets(W, f).forEach((s, i) => push(10 + i, { href: s.href, blur: s.blur, opacity: s.opacity, transform: f.transform, clip: f.clip }));
|
||||
break;
|
||||
}
|
||||
case 'fieldGrid': {
|
||||
const f = comp.fieldGrid; if (!f || f.enabled === false) break;
|
||||
const z0 = f.pos === 'behind' ? 5 : 25;
|
||||
gridSheets(W, f).forEach((s, i) => push(z0 + i, { href: s.href, blur: s.blur, opacity: s.opacity, transform: f.transform, clip: f.clip }));
|
||||
break;
|
||||
}
|
||||
case 'disk': {
|
||||
const d = comp.disk; if (!d || d.enabled === false) break;
|
||||
push(40, { href: uri(diskLayer(W, seed, d)), opacity: d.opacity ?? 1, transform: d.transform });
|
||||
break;
|
||||
}
|
||||
case 'bubble': {
|
||||
const b = comp.bubble; if (!b || b.enabled === false) break;
|
||||
// transparentBase (default true): float as an object (normal blend). When
|
||||
// false, the event keeps its paper base and composites via multiply.
|
||||
const tb = b.transparentBase !== false;
|
||||
push(50, { href: uri(bubbleLayer(W, seed, b)), opacity: b.opacity ?? 1, transform: b.transform, blend: tb ? undefined : 'multiply' });
|
||||
break;
|
||||
}
|
||||
case 'fiduciaries': {
|
||||
const fd = comp.fiduciaries; if (!fd || fd.enabled === false) break;
|
||||
const target = fd.target || [comp.bubble?.transform?.x ?? 0, comp.bubble?.transform?.y ?? 0];
|
||||
push(85, { href: uri(fiduciarySVG(W, { ...fd, target, seed })), opacity: 1, transform: fd.transform });
|
||||
break;
|
||||
}
|
||||
}
|
||||
const builder = GROUP_BUILDERS[group];
|
||||
if (builder) builder(comp, W, push, seed);
|
||||
// common per-layer OPACITY: multiply every piece's opacity (baseOpacity kept so
|
||||
// the UI can re-apply cheaply without regenerating the layer)
|
||||
const lo = comp[group] && comp[group].layerOpacity;
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
============================================================ */
|
||||
export const DEFAULT_COMPOSITION = {
|
||||
size: 1600, seed: 'MESON-5113',
|
||||
// ONE shared wind field (see src/field/wind.js). Consumed by fieldSea
|
||||
// (time-integrated warp), fieldLake/fieldGrid (instantaneous ripple) and
|
||||
// drift (seed advection). Groups opt in via their own `wind` sub-config.
|
||||
wind: { seed: 'ZEPHYR-001', strength: 1, scale: 1.6, gust: 0.35, time: 1 },
|
||||
background: {
|
||||
color: 'rgb(229,222,203)',
|
||||
film: { opacity: 0.6, density: 0.5, seed: 8 },
|
||||
@@ -16,16 +20,24 @@ export const DEFAULT_COMPOSITION = {
|
||||
glow: { strength: 0.55, followSun: true }, // lit-page glow; centre tracks the disk
|
||||
vignette: { strength: 0.4, mode: 'radial', cx: 0.5, cy: 0.48, radius: 0.75, angle: 90, start: 0.5 },
|
||||
},
|
||||
fieldLake: {
|
||||
enabled: false, layerOpacity: 1, transform: { x: 0, y: 0, rotation: 0, scale: 1 }, seed: 'LIMNOS-001',
|
||||
color: { hueBack: 0.55, hueFront: 0.56, sat: 0.45, light: 0.5 },
|
||||
layers: 2, chaos: 0.12, blips: 0.25, mound: 0, horizonY: 0.36, lines: 26,
|
||||
wind: { warp: 0.5 }, // instantaneous — the water shows the wind live
|
||||
},
|
||||
fieldSea: {
|
||||
enabled: true, layerOpacity: 1, transform: { x: 0, y: 0, rotation: 0, scale: 1 }, seed: 'VACUUM-5113',
|
||||
color: { hueBack: 0.54, hueFront: 0.47, sat: 0.6, light: 0.36 }, // light > ~0.6 → waves lighter than ground
|
||||
layers: 3, chaos: 0.3, blips: 0.7, mound: 0.3, horizonY: 0.36, lines: 46,
|
||||
wind: { warp: 0 }, // time-integrated — what the sand remembers
|
||||
},
|
||||
fieldGrid: {
|
||||
enabled: true, layerOpacity: 1, pos: 'over', style: 'floor', transform: { x: 0, y: 0, rotation: 0, scale: 1 },
|
||||
color: { hue: 0.5, hue2: 0.55, sat: 0.32, lightNear: 0.34, lightFar: 0.62 }, opacity: 0.44,
|
||||
pitch: 0.45, yaw: 0.42, persp: 1.1, dist: 2.8, nx: 16, nz: 24, originY: 0.34, ripple: { amp: 0, freqI: 0.5, freqK: 0.35, phase: 0 },
|
||||
resonance: { amp: 0, q: 14, axis: 'ties', hue: 0.06, sat: 0.7, light: 0.45 },
|
||||
wind: { ripple: 0 }, // instantaneous wind as floor height
|
||||
},
|
||||
disk: {
|
||||
enabled: true, layerOpacity: 1, transform: { x: 0, y: -0.26, rotation: 0, scale: 0.78 },
|
||||
@@ -37,6 +49,16 @@ export const DEFAULT_COMPOSITION = {
|
||||
primaries: 18, sweepers: 5, cosmics: 6, eloss: 0.34, bfield: 1.0, deltaRate: 0.6,
|
||||
showBoundary: true, boundaryR: 0.45, boundaryY: 0.35, boundaryOpacity: 0.4, instrument: 0.35,
|
||||
},
|
||||
flora: {
|
||||
enabled: false, layerOpacity: 1, transform: { x: 0, y: 0, rotation: 0, scale: 1 },
|
||||
palette: 'dunelake', saturation: 1.05, count: 1, scale: 0.5,
|
||||
pedicels: 48, droop: 0.35, spread: 1, burst: 0, floretSize: 1,
|
||||
clusterW: 0.9, clusterH: 0.5, // placement spread when count > 1 (no explicit umbels[])
|
||||
},
|
||||
drift: {
|
||||
enabled: false, layerOpacity: 1,
|
||||
palette: 'dunelake', count: 24, slip: 0.35, flutter: 0.5, settle: 0.06, tuft: 2,
|
||||
},
|
||||
fiduciaries: {
|
||||
enabled: true, layerOpacity: 1, label: 'auto', pencil: '#39312a', width: 1.0, arrow: true, corners: false, caption: '',
|
||||
},
|
||||
@@ -66,6 +88,21 @@ export const GROUPS_SCHEMA = [
|
||||
R('vignette.angle', 'Vignette angle°', 0, 360, 1),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'fieldLake', label: 'Field · Lake', transform: true, enable: true, controls: [
|
||||
R('color.hueBack', 'Hue · far', 0, 1, 0.005),
|
||||
R('color.hueFront', 'Hue · near', 0, 1, 0.005),
|
||||
R('color.sat', 'Saturation', 0, 1, 0.01),
|
||||
R('color.light', 'Wave luminosity', 0, 1, 0.01),
|
||||
R('layers', 'Plate layers', 1, 3, 1),
|
||||
R('chaos', 'Chaos', 0, 1, 0.01),
|
||||
R('blips', 'Blips', 0, 2, 0.05),
|
||||
R('horizonY', 'Horizon Y', 0.2, 0.6, 0.01),
|
||||
R('lines', '# lines', 8, 80, 1),
|
||||
R('wind.warp', 'Wind ripple', 0, 2, 0.02),
|
||||
{ path: 'seed', label: 'Seed', type: 'text' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'fieldSea', label: 'Field · Sea', transform: true, enable: true, controls: [
|
||||
R('color.hueBack', 'Hue · far', 0, 1, 0.005),
|
||||
@@ -78,6 +115,7 @@ export const GROUPS_SCHEMA = [
|
||||
R('mound', 'Mound', 0, 1, 0.01),
|
||||
R('horizonY', 'Horizon Y', 0.2, 0.6, 0.01),
|
||||
R('lines', '# lines', 16, 80, 1),
|
||||
R('wind.warp', 'Wind warp (dune memory)', 0, 2, 0.02),
|
||||
{ path: 'seed', label: 'Seed', type: 'text' },
|
||||
],
|
||||
},
|
||||
@@ -96,6 +134,7 @@ export const GROUPS_SCHEMA = [
|
||||
R('color.hue', 'Hue', 0, 1, 0.005),
|
||||
R('color.sat', 'Saturation', 0, 1, 0.01),
|
||||
R('ripple.amp', 'Floor ripple', 0, 2, 0.02),
|
||||
R('wind.ripple', 'Wind ripple', 0, 2, 0.02),
|
||||
R('resonance.amp', 'Resonance (high-Q)', 0, 1, 0.01),
|
||||
R('resonance.q', 'Resonance Q', 2, 40, 1),
|
||||
R('resonance.hue', 'Resonance hue', 0, 1, 0.005),
|
||||
@@ -131,6 +170,30 @@ export const GROUPS_SCHEMA = [
|
||||
R('instrument', 'Structural geometry', 0, 1, 0.01),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'flora', label: 'Flora · milkweed', transform: true, enable: true, controls: [
|
||||
{ path: 'palette', label: 'Palette', type: 'select', options: ['dunelake', 'magentarise', 'mono', 'kind', 'kindrise', 'kindlife', 'lifecycle'] },
|
||||
R('saturation', 'Saturation', 0, 1.5, 0.01),
|
||||
R('count', 'Umbels', 1, 7, 1),
|
||||
R('scale', 'Head size', 0.15, 1.2, 0.01),
|
||||
R('pedicels', 'Pedicels', 8, 80, 1),
|
||||
R('droop', 'Droop', 0, 1, 0.01),
|
||||
R('spread', 'Fan looseness', 0, 2, 0.01),
|
||||
R('burst', 'Burst (gone to seed)', 0, 1, 0.01),
|
||||
R('floretSize', 'Floret size', 0.3, 2.5, 0.01),
|
||||
{ path: 'seed', label: 'Seed', type: 'text' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'drift', label: 'Drift · seeds', enable: true, controls: [
|
||||
R('count', 'Seeds (cap)', 0, 80, 1),
|
||||
R('slip', 'Launch slip', 0, 1, 0.01),
|
||||
R('flutter', 'Coma flutter', 0, 1.5, 0.01),
|
||||
R('settle', 'Settle speed', 0, 0.3, 0.005),
|
||||
R('tuft', 'Tuft silks', 0, 5, 1),
|
||||
R('layerOpacity', 'Opacity', 0, 1, 0.01),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'fiduciaries', label: 'Fiduciaries', transform: true, enable: true, controls: [
|
||||
{ path: 'label', label: 'Label', type: 'text' },
|
||||
|
||||
@@ -143,6 +143,26 @@ export const TEMPLATES = [
|
||||
fiduciaries: { label: 'auto' },
|
||||
},
|
||||
},
|
||||
// 9 — DUNE LAKE · first of the HIDDEN-REALITIES series: natural subjects as
|
||||
// instrument photographs. One wind field, three detectors — dunes (time-
|
||||
// integrated), water (instantaneous), milkweed seed drift (advected); the
|
||||
// umbel is an interaction vertex grown botanically. Future series entries:
|
||||
// DNA/Photo 51 (helical heightFn rails), chlorophyll (porphyrin rosette,
|
||||
// green-paper inverted palette), CMB (power-spectrum modesFn carpet).
|
||||
{
|
||||
id: 'dune-lake', name: 'Dunes on a Great Lake', source: 'Hidden Realities', series: 'hidden-realities', reps: 3,
|
||||
seeds: ['LAKEMICH-0610', 'SLEEPING-BEAR-22', 'CRITICALDUNE-7'],
|
||||
over: {
|
||||
wind: { seed: 'ZEPHYR-011', strength: 0.8, scale: 1.6, gust: 0.4, time: 1.4 },
|
||||
background: { color: 'rgb(226,216,192)', glow: { strength: 0.4, followSun: false }, vignette: { strength: 0.32, cy: 0.42, radius: 0.9 } },
|
||||
fieldLake: { enabled: true, color: { hueBack: 0.555, hueFront: 0.52, sat: 0.42, light: 0.52 }, layers: 2, chaos: 0.1, blips: 0.2, mound: 0, lines: 24, horizonY: 0.4, wind: { warp: 0.55 }, clip: [0, 0.36, 1, 0.58] },
|
||||
fieldSea: { color: { hueBack: 0.09, hueFront: 0.07, sat: 0.42, light: 0.42 }, chaos: 0.22, blips: 0.35, mound: 0.55, horizonY: 0.56, lines: 52, wind: { warp: 0.9 } },
|
||||
fieldGrid: { enabled: false }, disk: { enabled: false }, bubble: { enabled: false },
|
||||
flora: { enabled: true, seed: 'ASCLEPIAS-1', palette: 'dunelake', count: 3, scale: 0.42, pedicels: 46, droop: 0.4, burst: 0.3, clusterW: 0.7, clusterH: 0.3, transform: { x: -0.34, y: 0.42, rotation: 0, scale: 1 } },
|
||||
drift: { enabled: true, count: 28, slip: 0.4, flutter: 0.55, tuft: 2 },
|
||||
fiduciaries: { label: 'ASCLEPIAS SYRIACA', target: [-0.34, 0.42], from: [0.35, -0.3] },
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// build the composition for a template at variation index i
|
||||
|
||||
72
src/field/wind.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/* ============================================================
|
||||
field/wind.js — the SHARED WIND FIELD: one invisible field,
|
||||
three detectors. The same seeded flow is sampled three ways:
|
||||
|
||||
displacement(x,y,T) time-integrated — what the SAND remembers
|
||||
(warps the dune ridgelines)
|
||||
vec(x,y,t) / scalar instantaneous — what the WATER shows
|
||||
(drives lake ripple phase)
|
||||
vec stepped advected — what the SEEDS trace
|
||||
(milkweed drift = test particles)
|
||||
|
||||
Divergence-free curl noise from a streamfunction ψ(x,y,t) built
|
||||
as a sum of K seeded sinusoidal modes plus a mean drift, so the
|
||||
velocity has a closed-form time integral (no numerics, fully
|
||||
deterministic). Coordinates are frame-normalized −1..1; typical
|
||||
|vec| ≈ strength.
|
||||
============================================================ */
|
||||
import { makeRng, range } from '../rng.js';
|
||||
|
||||
export function makeWindField(seed, opts = {}) {
|
||||
const o = Object.assign({
|
||||
modes: 6, scale: 1.6, strength: 1,
|
||||
drift: [0.6, 0.05], // prevailing wind (mean velocity, frame units)
|
||||
gust: 0.35, // how much the modes stir vs. the mean drift
|
||||
}, opts);
|
||||
const rng = makeRng(seed, 'wind');
|
||||
const modes = [];
|
||||
for (let m = 0; m < o.modes; m++) {
|
||||
const ang = range(rng, 0, Math.PI * 2);
|
||||
const k = range(rng, 0.6, 2.2) * o.scale; // low wavenumber: long swells
|
||||
modes.push({
|
||||
kx: Math.cos(ang) * k, ky: Math.sin(ang) * k,
|
||||
a: range(rng, 0.5, 1) / k, // energy at the large scales
|
||||
w: range(rng, 0.4, 1.4), // temporal frequency
|
||||
phi: range(rng, 0, Math.PI * 2),
|
||||
});
|
||||
}
|
||||
const norm = modes.reduce((s, m) => s + m.a * Math.hypot(m.kx, m.ky), 0) || 1;
|
||||
const g = o.gust * o.strength / norm; // mode velocity normaliser
|
||||
const dx0 = o.drift[0] * o.strength, dy0 = o.drift[1] * o.strength;
|
||||
|
||||
// instantaneous velocity: u = ∂ψ/∂y, v = −∂ψ/∂x (divergence-free) + drift
|
||||
const vec = (x, y, t = 0) => {
|
||||
let u = 0, v = 0;
|
||||
for (const m of modes) {
|
||||
const c = m.a * Math.cos(m.kx * x + m.ky * y + m.w * t + m.phi);
|
||||
u += m.ky * c; v -= m.kx * c;
|
||||
}
|
||||
return { u: u * g * modes.length + dx0, v: v * g * modes.length + dy0 };
|
||||
};
|
||||
|
||||
// Eulerian time integral 0..T of the velocity at a fixed point — the
|
||||
// closed-form "memory" of the wind (dune displacement field)
|
||||
const displacement = (x, y, T = 1) => {
|
||||
let dx = 0, dy = 0;
|
||||
for (const m of modes) {
|
||||
const p = m.kx * x + m.ky * y + m.phi;
|
||||
const s = m.a * (Math.sin(p + m.w * T) - Math.sin(p)) / m.w;
|
||||
dx += m.ky * s; dy -= m.kx * s;
|
||||
}
|
||||
return { dx: dx * g * modes.length + dx0 * T, dy: dy * g * modes.length + dy0 * T };
|
||||
};
|
||||
|
||||
// the streamfunction itself — a scalar to phase ripples with
|
||||
const scalar = (x, y, t = 0) => {
|
||||
let s = 0;
|
||||
for (const m of modes) s += m.a * Math.sin(m.kx * x + m.ky * y + m.w * t + m.phi);
|
||||
return s * o.strength / (modes.reduce((q, m) => q + m.a, 0) || 1);
|
||||
};
|
||||
|
||||
return { vec, displacement, scalar };
|
||||
}
|
||||
@@ -43,6 +43,13 @@ export function carpetSVG(size, opts = {}) {
|
||||
blips: 1.0, // density of the spiralling wave-packet excitations
|
||||
hue: 0.52, hue2: 0.55, sat: 0.55, lightNear: 0.34, lightFar: 0.62,
|
||||
strokeNear: 1.7, strokeFar: 0.5,
|
||||
// optional field injections (all default OFF → output unchanged):
|
||||
// warpFn(t, d) → extra normalized vertical displacement (×amp) — an
|
||||
// external field (e.g. wind) shaping the rows
|
||||
// phaseFn(t, r) → phase shift added to every base mode (shimmer)
|
||||
// modesFn(rng, o) → replace the base mode set entirely (e.g. a CMB
|
||||
// power-spectrum-shaped spectrum)
|
||||
warpFn: null, phaseFn: null, modesFn: null,
|
||||
}, opts);
|
||||
const W = size, H = size, u = size / 1000;
|
||||
const paper = resolveSubstrate(o.substrate).paper.flat;
|
||||
@@ -50,8 +57,10 @@ export function carpetSVG(size, opts = {}) {
|
||||
|
||||
// ---- base sea: low-frequency field modes (phase drifts slowly per row) ----
|
||||
const M = Math.round(4 + o.chaos * 8);
|
||||
const modes = [];
|
||||
for (let m = 0; m < M; m++) {
|
||||
let modes = [];
|
||||
if (o.modesFn) {
|
||||
modes = o.modesFn(rng, o);
|
||||
} else for (let m = 0; m < M; m++) {
|
||||
const f = range(rng, 0.4, 3.0 + o.chaos * 5); // low q: long swells dominate
|
||||
modes.push({ f, a: 1 / (1 + f * 1.0), phi: range(rng, 0, Math.PI * 2), drift: range(rng, -1, 1) * (0.06 + f * 0.02) });
|
||||
}
|
||||
@@ -78,7 +87,8 @@ export function carpetSVG(size, opts = {}) {
|
||||
|
||||
const value = (t, r) => {
|
||||
let s = 0;
|
||||
for (const m of modes) s += m.a * Math.sin(2 * Math.PI * m.f * t + m.phi + r * m.drift);
|
||||
const dphi = o.phaseFn ? o.phaseFn(t, r) : 0;
|
||||
for (const m of modes) s += m.a * Math.sin(2 * Math.PI * m.f * t + m.phi + r * m.drift + dphi);
|
||||
s /= norm;
|
||||
let blip = 0;
|
||||
for (const e of exc) {
|
||||
@@ -112,7 +122,8 @@ export function carpetSVG(size, opts = {}) {
|
||||
for (let i = 0; i <= npts; i++) {
|
||||
const t = i / npts;
|
||||
const e = env(t);
|
||||
pts.push({ x: cx - half + t * 2 * half, y: baseY[r] - amp * e * value(t, r) - amp * 0.55 * (e - eMin) * d });
|
||||
const warp = o.warpFn ? o.warpFn(t, d) * amp : 0;
|
||||
pts.push({ x: cx - half + t * 2 * half, y: baseY[r] - amp * e * value(t, r) - amp * 0.55 * (e - eMin) * d + warp });
|
||||
}
|
||||
const path = smoothPath(pts);
|
||||
const hue = o.hue + (o.hue2 - o.hue) * (1 - d);
|
||||
|
||||
@@ -26,6 +26,8 @@ export const SUBSTRATES = {
|
||||
vign: [42, 38, 54], feature: [58, 50, 72] },
|
||||
cyanotype:{ paper: { flat: [22, 48, 82], glowIn: [38, 70, 110], glowOut: [10, 22, 44] },
|
||||
vign: [6, 12, 22], feature: [180, 210, 235] },
|
||||
dune: { paper: { flat: [212, 196, 158], glowIn: [230, 214, 176], glowOut: [178, 160, 122] },
|
||||
vign: [58, 46, 28], feature: [120, 96, 60] },
|
||||
};
|
||||
|
||||
export function resolveSubstrate(id = 'vintage') {
|
||||
|
||||
@@ -48,6 +48,8 @@ export function perspFloorSVG(size, opts = {}) {
|
||||
nx: 14, nz: 22, yaw: 0, pitch: 0.5, roll: 0, persp: 1.0, dist: 3.0, zShift: 0,
|
||||
scale: 1.0, originX: 0, originY: 0.32,
|
||||
rippleAmp: 0, rippleFreqI: 0.5, rippleFreqK: 0.4, ripplePhase: 0,
|
||||
heightFn: null, // optional heightFn(i,k) → extra floor height (an external
|
||||
// field: wind ripple, a helical rail, …). null → unchanged.
|
||||
hue: 0.56, hue2: 0.5, sat: 0.26, lightNear: 0.32, lightFar: 0.62,
|
||||
stroke: 1.5, strokeFar: 0.45, opacityMul: 1,
|
||||
// high-Q RESONANCE on one axis, in a distinct colour (a standing wave threading
|
||||
@@ -65,7 +67,8 @@ export function perspFloorSVG(size, opts = {}) {
|
||||
|
||||
// project a floor point (i, k); returns screen px + depth + clip flag
|
||||
const proj = (i, k) => {
|
||||
const yWorld = o.rippleAmp ? o.rippleAmp * Math.sin(o.rippleFreqI * i + o.rippleFreqK * k + o.ripplePhase) : 0;
|
||||
const yWorld = (o.rippleAmp ? o.rippleAmp * Math.sin(o.rippleFreqI * i + o.rippleFreqK * k + o.ripplePhase) : 0)
|
||||
+ (o.heightFn ? o.heightFn(i, k) : 0);
|
||||
let x = i, y = yWorld, z = k;
|
||||
const x1 = x * cy + z * sy, z1 = -x * sy + z * cy, y1 = y;
|
||||
const y2 = y1 * cx - z1 * sx, z2 = y1 * sx + z1 * cx, x2 = x1;
|
||||
|
||||
@@ -77,6 +77,7 @@ const TONES = {
|
||||
cool: { flat: [180, 194, 209], gin: [199, 213, 227], gout: [146, 160, 178], vign: [30, 40, 56] },
|
||||
olive: { flat: [194, 197, 160], gin: [213, 216, 178], gout: [158, 161, 122], vign: [42, 46, 26] },
|
||||
neutral: { flat: [197, 196, 194], gin: [216, 215, 213], gout: [166, 165, 162], vign: [46, 45, 43] },
|
||||
dune: { flat: [212, 196, 158], gin: [230, 214, 176], gout: [178, 160, 122], vign: [58, 46, 28] },
|
||||
};
|
||||
export function paperTone(params, inv) {
|
||||
const tone = TONES[params.paperTone] || TONES.cream;
|
||||
@@ -127,14 +128,14 @@ function betaColor(beta, inv) {
|
||||
return hslToRgb(h, 0.68, inv ? (0.42 - 0.08 * (1 - b)) : 0.6);
|
||||
}
|
||||
// one distinct hue per particle kind (categorical)
|
||||
const KIND_HUE = { primary: 0.08, delta: 0.50, cosmic: 0.62, sweep: 0.34, vdecay: 0.85 };
|
||||
const KIND_HUE = { primary: 0.08, delta: 0.50, cosmic: 0.62, sweep: 0.34, vdecay: 0.85, pedicel: 0.26, floret: 0.93, seed: 0.12 };
|
||||
function kindColor(kind, inv) {
|
||||
return hslToRgb(KIND_HUE[kind] ?? 0.08, 0.72, inv ? 0.42 : 0.60);
|
||||
}
|
||||
// a restricted analogous scheme: each particle type a distinct shade within the
|
||||
// purple→magenta→pink band (for the simplified "magenta family" feel)
|
||||
// purple→magenta→pink band, nudged off the blue end (less blue in the purples)
|
||||
const MAG_HUE = { primary: 0.90, delta: 0.95, cosmic: 0.82, sweep: 0.86, vdecay: 0.79 };
|
||||
const MAG_HUE = { primary: 0.90, delta: 0.95, cosmic: 0.82, sweep: 0.86, vdecay: 0.79, pedicel: 0.86, floret: 0.92, seed: 0.82 };
|
||||
// the contrasting feature/disk accent — a single monochrome hue. Defaults to the
|
||||
// burnt-orange that pairs with the magenta family; `magentarise` exposes hue/sat as
|
||||
// dials (diskHue/diskSat) so the trace-vs-disk colour relationship is sweepable.
|
||||
@@ -226,6 +227,33 @@ export const PALETTES = {
|
||||
feature: (e) => featureHue(e.inv, e.diskHue ?? 0.06, e.diskSat ?? 0.82), // disk + furniture
|
||||
},
|
||||
|
||||
// the dune & lake botanical feel: pedicels keep a dry sage-stem green,
|
||||
// florets glow dusty milkweed rose intensifying along the life (vertex →
|
||||
// floret knob), released seeds run near-paper cream — pale silk on the wind.
|
||||
// The feature ink is driftwood brown for any furniture.
|
||||
dunelake: {
|
||||
id: 'dunelake', label: 'Dune & lake (milkweed)',
|
||||
bubbleInk: (b, e) => {
|
||||
const t = Math.round(clamp(b.life, 0, 1) * 16) / 16;
|
||||
const k = b.track.kind;
|
||||
if (k === 'seed') {
|
||||
// silk: faint at release, gathering ink toward the landing
|
||||
const lo = e.inv ? 0.88 : 0.30, hi = e.inv ? 0.66 : 0.55;
|
||||
return hslToRgb(0.10, 0.30, lo + (hi - lo) * t);
|
||||
}
|
||||
if (k === 'floret') {
|
||||
// dusty rose, saturating into the rosette tip
|
||||
const lo = e.inv ? 0.74 : 0.34, hi = e.inv ? 0.52 : 0.58;
|
||||
return hslToRgb(0.93 + (e.traceHue ?? 0), 0.38 + 0.30 * t, lo + (hi - lo) * t);
|
||||
}
|
||||
// pedicel (and any guest kind): sage stem, faint at the vertex,
|
||||
// warming toward the floret end
|
||||
const lo = e.inv ? 0.80 : 0.22, hi = e.inv ? 0.50 : 0.46;
|
||||
return hslToRgb(0.24 - 0.10 * t, 0.30 + 0.18 * t, lo + (hi - lo) * t);
|
||||
},
|
||||
feature: (e) => hslToRgb(0.08, 0.45, e.inv ? 0.40 : 0.34), // driftwood
|
||||
},
|
||||
|
||||
// a complete "chemistry": overrides paper + ink together (deep Prussian-blue
|
||||
// ground, pale lines) — the blueprint/cyanotype look.
|
||||
cyanotype: {
|
||||
|
||||
@@ -22,6 +22,8 @@ const TRACK_LAYERS = [
|
||||
{ id: 'tracks-cosmic', label: 'Tracks · cosmic & sweepers', kinds: ['cosmic', 'sweep'] },
|
||||
{ id: 'tracks-vdecay', label: 'Tracks · V-decays', kinds: ['vdecay'] },
|
||||
{ id: 'tracks-delta', label: 'Tracks · δ-rays (curls)', kinds: ['delta'] },
|
||||
{ id: 'tracks-flora', label: 'Flora · umbels & florets', kinds: ['pedicel', 'floret'] },
|
||||
{ id: 'tracks-drift', label: 'Drift · seeds on the wind', kinds: ['seed'] },
|
||||
];
|
||||
|
||||
// rgb[0..255] → [h,s,l] (0..1), for hue-preserving darkening
|
||||
|
||||
73
src/scene/drift.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/* ============================================================
|
||||
drift.js — milkweed seeds as test particles in the wind.
|
||||
The sibling of track.js: where a charged particle is BENT by
|
||||
the B-field, a coma-tufted seed is ADVECTED by the flow. Same
|
||||
output contract ({pts:[{x,y,beta,theta}], kind, …}), so the
|
||||
shared bubble sampler and both renderers work verbatim.
|
||||
|
||||
β ↔ airspeed is the energy-loss analogue: a stalling seed =
|
||||
rising ionisation = denser bubbles, so landings end in the
|
||||
same dense terminal cluster as a particle's end of range.
|
||||
============================================================ */
|
||||
import { gauss, range } from '../rng.js';
|
||||
|
||||
/* Advect one seed through the wind. state: {x, y, theta, slip}
|
||||
(slip = the seed's own airspeed along its heading, decaying). */
|
||||
export function advectTrack(state, wind, opts = {}) {
|
||||
const o = Object.assign({
|
||||
maxSteps: 1400, ds: 0.004, bound: 1.15,
|
||||
settle: 0.06, // |v| below this → the seed lands
|
||||
flutter: 0.5, // coma wobble (perpendicular jitter)
|
||||
drag: 2.2, // slip decay per unit path
|
||||
vRef: 1.0, // speed that maps to β ≈ 0.9
|
||||
rng: Math.random,
|
||||
}, opts);
|
||||
let { x, y, theta, slip = 0.3 } = state;
|
||||
const pts = [];
|
||||
for (let i = 0; i < o.maxSteps; i++) {
|
||||
const w = wind.vec(x, y);
|
||||
let vx = w.u + Math.cos(theta) * slip;
|
||||
let vy = w.v + Math.sin(theta) * slip;
|
||||
const sp = Math.hypot(vx, vy);
|
||||
if (sp < o.settle && i > 4) break; // stalled → landed
|
||||
const beta = Math.min(0.92, Math.max(0.15, (sp / o.vRef) * 0.9));
|
||||
pts.push({ x, y, beta, theta: Math.atan2(vy, vx) });
|
||||
x += (vx / sp) * o.ds; y += (vy / sp) * o.ds;
|
||||
// coma flutter: a small heading kick, stronger when the air is slow
|
||||
theta = Math.atan2(vy, vx) + gauss(o.rng) * o.flutter * 0.09 / Math.max(sp, 0.35);
|
||||
slip *= Math.max(0, 1 - o.drag * o.ds);
|
||||
if (Math.abs(x) > o.bound || Math.abs(y) > o.bound) break;
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
/* Wrap released seeds into renderable tracks. Each seed may carry a small
|
||||
"tuft bundle" of offset sub-tracks — the parallel silks of the coma. */
|
||||
export function generateDrift(params, wind, seeds, rng) {
|
||||
const o = Object.assign({
|
||||
count: 24, // cap on seeds taken
|
||||
slip: 0.35, flutter: 0.5, settle: 0.06, vRef: 1.0,
|
||||
tuft: 2, // sub-tracks per seed beyond the main silk
|
||||
}, params);
|
||||
const tracks = [];
|
||||
const take = seeds.slice(0, Math.max(0, Math.round(o.count)));
|
||||
for (const s of take) {
|
||||
const n = 1 + Math.max(0, Math.round(o.tuft));
|
||||
for (let k = 0; k < n; k++) {
|
||||
const perp = s.theta + Math.PI / 2;
|
||||
const off = k === 0 ? 0 : gauss(rng) * 0.005;
|
||||
const pts = advectTrack(
|
||||
{ x: s.x + Math.cos(perp) * off, y: s.y + Math.sin(perp) * off, theta: s.theta, slip: o.slip * range(rng, 0.7, 1.3) },
|
||||
wind,
|
||||
{ flutter: o.flutter, settle: o.settle, vRef: o.vRef, rng },
|
||||
);
|
||||
if (pts.length < 2) continue;
|
||||
tracks.push({
|
||||
pts, kind: 'seed', weight: k === 0 ? range(rng, 0.65, 0.85) : range(rng, 0.35, 0.55),
|
||||
q: 1, z: gauss(rng) * 0.3, age: 0,
|
||||
jitter: 0.004, densityScale: 1.4, sizeScale: 0.8,
|
||||
});
|
||||
}
|
||||
}
|
||||
return tracks;
|
||||
}
|
||||
80
src/scene/umbel.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/* ============================================================
|
||||
umbel.js — the milkweed flower head as a particle vertex.
|
||||
An umbel IS interaction-vertex geometry grown botanically:
|
||||
30–80 pedicels radiate from one point, each terminating in a
|
||||
five-fold floret. We model pedicels as direct parametric arcs
|
||||
(the delta.js precedent — shape the curve, don't fight the
|
||||
integrator). β runs HIGH at the vertex and falls toward the
|
||||
tip, so 1/β² bubble density concentrates ink at the floret
|
||||
knob — the head reads as a vertex with glowing terminals.
|
||||
|
||||
burst (0..1) releases pedicels: the floret is gone to silk,
|
||||
the pedicel frays, and a seed {x, y, theta} is handed to the
|
||||
drift system. Release decisions come from the SAME rng stream,
|
||||
so flora and drift layers calling generateUmbel with identical
|
||||
inputs agree exactly on the release points (no shared state).
|
||||
============================================================ */
|
||||
import { gauss, range } from '../rng.js';
|
||||
|
||||
/* Build one umbel. Returns { tracks, seeds }. */
|
||||
export function generateUmbel(params, rng) {
|
||||
const o = Object.assign({
|
||||
x: 0, y: 0, scale: 0.5, // scale ~ head radius in frame units × 0.36
|
||||
pedicels: 48, droop: 0.35, // gravity sag of each pedicel
|
||||
spread: 1.0, // angular jitter / fan looseness
|
||||
burst: 0, // 0 closed … 1 fully released to seed
|
||||
floretSize: 1,
|
||||
}, params);
|
||||
const tracks = [], seeds = [];
|
||||
const R = 0.18 * o.scale; // pedicel reach
|
||||
const N = Math.max(3, Math.round(o.pedicels));
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
const ang = (i / N) * Math.PI * 2 + gauss(rng) * 0.22 * o.spread;
|
||||
const len = R * range(rng, 0.82, 1.12);
|
||||
const droopAmt = o.droop * (0.5 + 0.5 * rng()) * len;
|
||||
const released = rng() < o.burst;
|
||||
const reach = released ? range(rng, 0.65, 0.9) : 1; // frayed pedicels run short
|
||||
const steps = 22;
|
||||
const pts = [];
|
||||
for (let s = 0; s <= steps; s++) {
|
||||
const f = (s / steps) * reach;
|
||||
// radial run + quadratic gravity sag (the umbel's soft droop)
|
||||
const px = o.x + Math.cos(ang) * len * f;
|
||||
const py = o.y + Math.sin(ang) * len * f + droopAmt * f * f;
|
||||
// β: hot at the vertex → slow at the tip ⇒ ink gathers at the floret
|
||||
const beta = 0.8 - 0.6 * f;
|
||||
const theta = Math.atan2(Math.sin(ang) * len + 2 * droopAmt * f, Math.cos(ang) * len);
|
||||
pts.push({ x: px, y: py, beta, theta });
|
||||
}
|
||||
tracks.push({
|
||||
pts, kind: 'pedicel', weight: range(rng, 0.8, 1), q: i % 2 ? 1 : -1,
|
||||
z: gauss(rng) * 0.2, age: 0, jitter: released ? 0.0034 : 0.0016,
|
||||
});
|
||||
|
||||
const tip = pts[pts.length - 1];
|
||||
if (released) {
|
||||
seeds.push({ x: tip.x, y: tip.y, theta: tip.theta });
|
||||
continue; // gone to silk — no floret
|
||||
}
|
||||
// five-fold floret: petal strokes fanned about the tip tangent
|
||||
const fl = 0.016 * o.scale * o.floretSize;
|
||||
const off = range(rng, 0, Math.PI * 2);
|
||||
for (let p = 0; p < 5; p++) {
|
||||
const pa = off + (p / 5) * Math.PI * 2;
|
||||
const fpts = [];
|
||||
for (let s = 0; s <= 6; s++) {
|
||||
const f = s / 6;
|
||||
fpts.push({
|
||||
x: tip.x + Math.cos(pa) * fl * f, y: tip.y + Math.sin(pa) * fl * f,
|
||||
beta: 0.25, theta: pa,
|
||||
});
|
||||
}
|
||||
tracks.push({
|
||||
pts: fpts, kind: 'floret', weight: range(rng, 0.7, 0.95), q: 1,
|
||||
z: gauss(rng) * 0.15, age: 0, sizeScale: 1.2,
|
||||
});
|
||||
}
|
||||
}
|
||||
return { tracks, seeds };
|
||||
}
|
||||
124
tools/dunelake.mjs
Normal file
@@ -0,0 +1,124 @@
|
||||
/* ============================================================
|
||||
dunelake.mjs — DUNES ON A GREAT LAKE WITH MILKWEED.
|
||||
First plate of the hidden-realities series: one invisible wind
|
||||
field made visible by three detectors — dunes (its time
|
||||
integral, what the sand remembers), water (its instantaneous
|
||||
trace), milkweed seeds (its advection). The umbel is a particle
|
||||
vertex grown botanically.
|
||||
|
||||
A curated variation matrix in the liberation.mjs manner:
|
||||
worlds (seed × wind character) × horizons × milkweed states ×
|
||||
palettes. Emits SVGs + exportable .mjs compositions + gallery.
|
||||
Usage: node tools/dunelake.mjs [size]
|
||||
============================================================ */
|
||||
import { writeFileSync, mkdirSync } from 'node:fs';
|
||||
import { DEFAULT_COMPOSITION } from '../src/compose/schema.js';
|
||||
import { renderComposition } from '../src/compose/composition.js';
|
||||
|
||||
const SIZE = +(process.argv[2] || 1300);
|
||||
const OUT = 'output/dunelake';
|
||||
mkdirSync(OUT, { recursive: true });
|
||||
const merge = (a, b) => { const o = { ...a }; for (const k in b) o[k] = (b[k] && typeof b[k] === 'object' && !Array.isArray(b[k])) ? merge(a[k] || {}, b[k]) : b[k]; return o; };
|
||||
|
||||
/* The landscape base: no collision event, no sun — the subjects are the
|
||||
field's three detectors. horizon = waterline (frame fraction). */
|
||||
const base = (seed, windSeed, windStrength, horizon, over = {}) => {
|
||||
const hClip = horizon; // lake band ends where dunes begin
|
||||
const c = merge(JSON.parse(JSON.stringify(DEFAULT_COMPOSITION)), merge({
|
||||
seed,
|
||||
wind: { seed: windSeed, strength: windStrength, scale: 1.6, gust: 0.4, time: 1.4 },
|
||||
background: {
|
||||
color: 'rgb(226,216,192)',
|
||||
glow: { strength: 0.4, followSun: false },
|
||||
vignette: { strength: 0.32, mode: 'radial', cy: 0.42, radius: 0.9 },
|
||||
film: { opacity: 0.5 }, aging: { opacity: 0.35, scratches: 3 }, grain: { opacity: 0.38 },
|
||||
},
|
||||
// WATER: a flat far band, instantaneous wind, cool — clipped above the dune line
|
||||
fieldLake: {
|
||||
enabled: true, seed: 'LIMNOS-' + seed,
|
||||
color: { hueBack: 0.555, hueFront: 0.52, sat: 0.42, light: 0.52 },
|
||||
layers: 2, chaos: 0.1, blips: 0.2, mound: 0, lines: 24,
|
||||
horizonY: Math.max(0.2, horizon - 0.16), wind: { warp: 0.55 },
|
||||
clip: [0, Math.max(0, horizon - 0.2), 1, horizon + 0.02],
|
||||
},
|
||||
// DUNES: the ridgeline carpet warped by the wind's time integral, warm sand
|
||||
fieldSea: {
|
||||
seed: 'AEOLIAN-' + seed,
|
||||
color: { hueBack: 0.09, hueFront: 0.07, sat: 0.42, light: 0.42 },
|
||||
layers: 3, chaos: 0.22, blips: 0.35, mound: 0.55, horizonY: horizon, lines: 52,
|
||||
wind: { warp: 0.9 },
|
||||
},
|
||||
fieldGrid: { enabled: false },
|
||||
disk: { enabled: false },
|
||||
bubble: { enabled: false },
|
||||
// MILKWEED: vertex-flowers on the foredune
|
||||
flora: {
|
||||
enabled: true, seed: 'ASCLEPIAS-' + seed, palette: 'dunelake',
|
||||
count: 3, scale: 0.42, pedicels: 46, droop: 0.4, burst: 0.25,
|
||||
clusterW: 0.7, clusterH: 0.3,
|
||||
transform: { x: -0.34, y: 0.42, rotation: 0, scale: 1 },
|
||||
},
|
||||
drift: { enabled: true, count: 28, slip: 0.4, flutter: 0.55, tuft: 2 },
|
||||
fiduciaries: { enabled: true, label: 'ASCLEPIAS SYRIACA', arrow: true, target: [-0.34, 0.42], from: [0.35, -0.3], caption: 'wind · integrated | instantaneous | advected' },
|
||||
}, over));
|
||||
return c;
|
||||
};
|
||||
|
||||
// dusk: warm-on-cool — sand holds the late light, the water goes slate
|
||||
const dusk = {
|
||||
background: { color: 'rgb(210,190,170)', glow: { strength: 0.5 } },
|
||||
fieldSea: { color: { hueBack: 0.05, hueFront: 0.95, sat: 0.5, light: 0.4 } },
|
||||
fieldLake: { color: { hueBack: 0.62, hueFront: 0.58, sat: 0.5, light: 0.42 } },
|
||||
};
|
||||
// nocturne: the night-plate move — dark ground, pale silks (liberation #11)
|
||||
const nocturne = {
|
||||
background: { color: 'rgb(22,23,30)', glow: { strength: 0.3, followSun: false }, vignette: { strength: 0.2 }, film: { opacity: 0.28 }, grain: { opacity: 0.3 } },
|
||||
fieldSea: { color: { hueBack: 0.6, hueFront: 0.08, sat: 0.3, light: 0.62 } },
|
||||
fieldLake: { color: { hueBack: 0.58, hueFront: 0.56, sat: 0.4, light: 0.66 } },
|
||||
fiduciaries: { pencil: '#cfc4a8' },
|
||||
};
|
||||
|
||||
const W = [
|
||||
{ id: 'breeze', seed: 'ZEPHYR-011', strength: 0.55 },
|
||||
{ id: 'gale', seed: 'BOREAS-104', strength: 1.25 },
|
||||
];
|
||||
const SEEDS = ['LAKEMICH-0610', 'SLEEPING-BEAR-22', 'CRITICALDUNE-7'];
|
||||
|
||||
const V = [];
|
||||
for (const s of SEEDS) {
|
||||
for (const w of W) {
|
||||
const tag = `${s.split('-')[0].toLowerCase()}-${w.id}`;
|
||||
// big-sky vs big-water horizons
|
||||
V.push({ name: `${tag}_low-horizon`, note: `${w.id} · big sky, dunes low (${s})`,
|
||||
comp: base(s, w.seed, w.strength, 0.62) });
|
||||
V.push({ name: `${tag}_high-water`, note: `${w.id} · big water, high dune line (${s})`,
|
||||
comp: base(s, w.seed, w.strength, 0.44, { fieldSea: { lines: 44 }, flora: { transform: { x: -0.3, y: 0.5 } }, fiduciaries: { target: [-0.3, 0.5] } }) });
|
||||
}
|
||||
}
|
||||
// milkweed states — closed / bursting / full release streaming across the lake
|
||||
const sBurst = SEEDS[0], sFull = SEEDS[1];
|
||||
V.push({ name: 'states_closed-left', note: 'umbels closed — the vertex before the decay',
|
||||
comp: base(sBurst, W[0].seed, W[0].strength, 0.56, { flora: { burst: 0, count: 2, transform: { x: -0.5, y: 0.38 } }, drift: { enabled: false }, fiduciaries: { target: [-0.5, 0.38], caption: 'pre-release · all florets held' } }) });
|
||||
V.push({ name: 'states_bursting-right', note: 'right-third bursting — half the florets gone to silk',
|
||||
comp: base(sBurst, W[1].seed, W[1].strength, 0.56, { flora: { burst: 0.55, transform: { x: 0.42, y: 0.44 } }, drift: { count: 40 }, fiduciaries: { target: [0.42, 0.44], caption: 'release fraction 0.55' } }) });
|
||||
V.push({ name: 'states_full-release', note: 'off-corner full burst — seeds streaming across the water',
|
||||
comp: base(sFull, W[1].seed, 1.4, 0.5, { flora: { burst: 1, count: 2, transform: { x: -0.78, y: 0.62 }, scale: 0.5 }, drift: { count: 64, slip: 0.5 }, fiduciaries: { target: [-0.78, 0.62], from: [0.4, -0.35], caption: 'all silk · the field made visible' } }) });
|
||||
|
||||
// palette rows over one world: day-sand (the base), dusk, nocturne
|
||||
V.push({ name: 'palette_dusk', note: 'dusk — sand holds the late light, slate water',
|
||||
comp: base(SEEDS[2], W[0].seed, 0.8, 0.55, dusk) });
|
||||
V.push({ name: 'palette_nocturne', note: 'nocturne — dark plate, pale silks (night-plate move)',
|
||||
comp: base(SEEDS[2], W[1].seed, 1.1, 0.55, merge(nocturne, { flora: { burst: 0.6 }, drift: { count: 48 } })) });
|
||||
|
||||
console.log(`dunelake — ${V.length} compositions → ${OUT}/`);
|
||||
for (const v of V) {
|
||||
writeFileSync(`${OUT}/${v.name}.svg`, renderComposition(v.comp, SIZE));
|
||||
writeFileSync(`${OUT}/${v.name}.mjs`, `/* dune-lake-milkweed · ${v.note} */\nexport const composition = ${JSON.stringify(v.comp, null, 2)};\n`);
|
||||
console.log(` ${v.name} — ${v.note}`);
|
||||
}
|
||||
writeFileSync(`${OUT}/matrix.html`, `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Dunes on a Great Lake — one wind, three detectors</title>
|
||||
<style>html,body{margin:0;background:#15140f;color:#cabfa6;font:12px ui-monospace,monospace}h1{font-weight:400;letter-spacing:.2em;text-transform:uppercase;color:#9fb7af;padding:18px 14px 0}p.sub{color:#8a8068;padding:0 14px;margin:6px 0 0}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;padding:14px}figure{margin:0;position:relative;background:#fff;overflow:hidden}img{width:100%;display:block}figcaption{position:absolute;left:0;bottom:0;right:0;padding:6px 9px;font:12px ui-monospace,monospace;color:#fff;background:linear-gradient(transparent,#000d)}</style></head><body>
|
||||
<h1>Dunes on a Great Lake with Milkweed (${V.length})</h1>
|
||||
<p class="sub">one invisible wind field · three detectors — sand (integrated) · water (instantaneous) · seeds (advected)</p>
|
||||
<div class="grid">${V.map(v => `<figure><img src="${v.name}.svg"><figcaption>${v.note}</figcaption></figure>`).join('')}</div></body></html>`);
|
||||
console.log(`-> ${OUT}/matrix.html`);
|
||||