Skip to content

Commit 2f53596

Browse files
committed
Simplify controls and boost visuals
1 parent ade2bd5 commit 2f53596

5 files changed

Lines changed: 20 additions & 109 deletions

File tree

src/post.wgsl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
// All passes draw a single fullscreen triangle. The scene is rendered to an HDR
33
// (rgba16float) target; bloom is computed at reduced resolution and added back.
44

5-
const THRESHOLD: f32 = 0.56; // brightness above which a pixel blooms
6-
const BLOOM_STRENGTH: f32 = 0.48;
7-
const EXPOSURE: f32 = 1.08;
5+
const THRESHOLD: f32 = 0.42; // brightness above which a pixel blooms
6+
const BLOOM_STRENGTH: f32 = 0.72;
7+
const EXPOSURE: f32 = 1.20;
88

99
// Motion-trail feedback: each frame the HDR scene is multiplied by this factor
1010
// before new particles are drawn on top (see `fade` below + postprocess.rs).
1111
// Higher = longer-lived comet tails. Tuned against the particle/bloom gains so
1212
// overlapping trails glow without blowing out to solid white.
13-
const TRAIL_PERSISTENCE: f32 = 0.89;
13+
const TRAIL_PERSISTENCE: f32 = 0.91;
1414

1515
// Ambient background depth. Instead of fading to flat #000, the composite adds a
1616
// faint deep-blue/violet radial glow so the void reads as atmospheric. Kept
1717
// subtle so it never washes out the creatures or competes with the bloom; the
1818
// glow is brightest at the centre and falls to a near-black vignette at the
1919
// corners. These are pre-tonemap HDR intensities.
2020
const AMBIENT_COLOR: vec3<f32> = vec3<f32>(0.20, 0.11, 0.45); // deep blue-violet
21-
const AMBIENT_CENTER: f32 = 0.12; // glow intensity at screen centre
22-
const AMBIENT_EDGE: f32 = 0.018; // residual glow at the corners (vignette floor)
21+
const AMBIENT_CENTER: f32 = 0.14; // glow intensity at screen centre
22+
const AMBIENT_EDGE: f32 = 0.02; // residual glow at the corners (vignette floor)
2323

2424
struct VsOut {
2525
@builtin(position) pos: vec4<f32>,

src/shader.wgsl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
118118
let highlight = smoothstep(0.32, 0.0, length(shaped_uv - highlight_offset));
119119

120120
let vivid = pow(max(in.color, vec3<f32>(0.001)), vec3<f32>(0.82));
121-
let cytoplasm = vivid * (body * 0.62 + inner * 0.32 + halo * 0.24);
122-
let membrane = mix(vivid, vec3<f32>(0.88, 0.96, 1.0), 0.38) * soft_edge * 0.28;
123-
let nucleus_rgb = mix(vivid, vec3<f32>(0.12, 0.16, 0.22), 0.38) * nucleus * 0.24;
124-
let highlight_rgb = vec3<f32>(1.0, 0.96, 0.84) * highlight * 0.18;
121+
let cytoplasm = vivid * (body * 0.86 + inner * 0.46 + halo * 0.34);
122+
let membrane = mix(vivid, vec3<f32>(0.9, 0.98, 1.0), 0.40) * soft_edge * 0.42;
123+
let nucleus_rgb = mix(vivid, vec3<f32>(0.12, 0.16, 0.22), 0.34) * nucleus * 0.28;
124+
let highlight_rgb = vec3<f32>(1.0, 0.96, 0.84) * highlight * 0.26;
125125
let rgb = cytoplasm + membrane + nucleus_rgb + highlight_rgb;
126126

127-
return vec4<f32>(rgb, body * 0.82);
127+
return vec4<f32>(rgb, body * 0.9);
128128
}
129129

130130
// ---------------------------------------------------------------------------
@@ -182,8 +182,8 @@ fn food_fs(in: FoodVertexOutput) -> @location(0) vec4<f32> {
182182
// Calm teal/green nourishment colour, kept dim so it reads as ambient food
183183
// and never competes with the creatures or the bloom. Scaled by the patch's
184184
// current intensity so a depleted patch visibly fades.
185-
let teal = vec3<f32>(0.07, 0.38, 0.30);
186-
let brightness = 0.58;
185+
let teal = vec3<f32>(0.075, 0.42, 0.33);
186+
let brightness = 0.68;
187187
let rgb = teal * soft * brightness * in.intensity;
188188

189189
return vec4<f32>(rgb, soft);

web/css/style.css

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -186,27 +186,7 @@ main {
186186
0 0 22px rgba(var(--accent-rgb), 0.18);
187187
}
188188

189-
/* ===== Seed + actions ===== */
190-
.toprow {
191-
display: flex;
192-
gap: 8px;
193-
}
194-
#seed-input {
195-
flex: 1;
196-
min-width: 0;
197-
background: rgba(255, 255, 255, 0.06);
198-
border: 1px solid var(--border);
199-
color: var(--text-strong);
200-
font-family: var(--font-mono);
201-
font-size: 13px;
202-
padding: 8px 10px;
203-
border-radius: 8px;
204-
outline: none;
205-
}
206-
#seed-input:focus {
207-
border-color: rgba(var(--accent-rgb), 0.7);
208-
box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18);
209-
}
189+
/* ===== Actions ===== */
210190
.btn {
211191
font-family: var(--font-mono);
212192
font-size: 11px;
@@ -238,32 +218,6 @@ main {
238218
text-align: center;
239219
}
240220

241-
/* ===== Seed readout ===== */
242-
.seed-readout {
243-
background: rgba(255, 255, 255, 0.04);
244-
border: 1px solid var(--border);
245-
border-radius: 10px;
246-
padding: 8px 10px;
247-
display: flex;
248-
align-items: center;
249-
justify-content: space-between;
250-
gap: 12px;
251-
}
252-
.seed-readout .k {
253-
font-family: var(--font-mono);
254-
font-size: 9px;
255-
letter-spacing: 0.16em;
256-
text-transform: uppercase;
257-
color: var(--muted);
258-
}
259-
.seed-readout .v {
260-
font-family: var(--font-mono);
261-
font-size: 13px;
262-
font-weight: 700;
263-
color: var(--accent);
264-
line-height: 1;
265-
}
266-
267221
/* ===== Control groups ===== */
268222
.group {
269223
display: flex;

web/index.html

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,13 @@
3434
</button>
3535

3636
<div id="controls-body">
37-
<!-- Seed + reset -->
38-
<div class="toprow">
39-
<input type="text" id="seed-input" value="12345" placeholder="seed (blank = random)" />
40-
<button id="reset" class="btn">Reset</button>
41-
</div>
42-
4337
<!-- Instant actions -->
4438
<div class="actions">
39+
<button id="reset" class="btn act" type="button">Reset</button>
4540
<button id="cull" class="btn act" type="button" title="Remove half the population">Cull</button>
4641
<button id="bloom" class="btn act" type="button" title="Spawn a burst of new life">Bloom</button>
4742
</div>
4843

49-
<!-- Seed readout -->
50-
<div class="seed-readout">
51-
<span class="k">Seed</span>
52-
<span class="v" id="seed-display"></span>
53-
</div>
54-
5544
<!-- Ecosystem controls -->
5645
<div class="group">
5746
<div class="group-title">Ecosystem</div>

web/js/app.js

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const DEFAULT_CONFIG = {
5353
// Serialized once at module load — the config is constant, so init() and reset()
5454
// reuse it instead of re-stringifying on every (re)construction.
5555
const CONFIG_JSON = JSON.stringify(DEFAULT_CONFIG);
56+
const DEFAULT_SEED = 12345;
5657

5758
// Ecosystem + motion sliders, each mapping one DOM slider to one SimParam.
5859
// Adding a slider is a one-line entry here plus the markup in index.html.
@@ -73,9 +74,6 @@ class EvolutionApp {
7374
this.renderer = null;
7475
this.canvas = null;
7576
this.animationId = null;
76-
this.lastTime = 0;
77-
this.frameCount = 0;
78-
this.fps = 0;
7977
// Render-upload gating: the instance buffer is repacked only when the sim
8078
// step advances (see render()); other frames re-use the cached pointer.
8179
this.lastRenderedStep = -1;
@@ -225,18 +223,16 @@ class EvolutionApp {
225223
document.getElementById("cull").addEventListener("click", () => {
226224
this.simulation.cull(0.5);
227225
this.lastRenderedStep = -1; // force a repack so the change shows at once
228-
this.updateStats();
229226
});
230227
document.getElementById("bloom").addEventListener("click", () => {
231228
this.simulation.bloom(500);
232229
this.lastRenderedStep = -1;
233-
this.updateStats();
234230
});
235231

236232
// Parameter sliders (table-driven — see SLIDERS) plus the sim-speed control.
237233
this.setupSliders();
238234

239-
// Keyboard shortcuts (ignored while typing in the seed box)
235+
// Keyboard shortcuts (ignored while editing controls)
240236
document.addEventListener("keydown", (e) => {
241237
if (e.target.tagName === "INPUT") return;
242238
if (e.key === "h" || e.key === "H") {
@@ -310,45 +306,22 @@ class EvolutionApp {
310306
});
311307
}
312308

313-
// Size the canvas to the window and build a fresh simulation. The seed box, if
314-
// set, reproduces a specific run; empty means a wall-clock seed. Shared by
315-
// init() and reset() so construction lives in one place.
309+
// Size the canvas to the window and build a fresh deterministic simulation.
310+
// Shared by init() and reset() so construction lives in one place.
316311
createSimulation() {
317312
this.canvas.width = window.innerWidth;
318313
this.canvas.height = window.innerHeight;
319314
const worldSize = Math.max(this.canvas.width, this.canvas.height);
320-
const seedText = document.getElementById("seed-input")?.value.trim();
321-
const seed = seedText ? Number(seedText) : NaN;
322-
this.simulation = Number.isFinite(seed)
323-
? WebSimulation.with_seed(worldSize, CONFIG_JSON, seed)
324-
: new WebSimulation(worldSize, CONFIG_JSON);
325-
this.updateSeedDisplay();
315+
this.simulation = WebSimulation.with_seed(worldSize, CONFIG_JSON, DEFAULT_SEED);
326316
this.lastRenderedStep = -1; // fresh sim — force a repack on the next frame
327317
}
328318

329319
reset() {
330320
this.createSimulation();
331-
this.updateStats();
332-
}
333-
334-
updateSeedDisplay() {
335-
const el = document.getElementById("seed-display");
336-
if (el && this.simulation) {
337-
el.textContent = String(this.simulation.get_seed());
338-
}
339321
}
340322

341323
startRenderLoop() {
342324
const animate = (currentTime) => {
343-
// Calculate FPS
344-
this.frameCount++;
345-
if (currentTime - this.lastTime >= 1000) {
346-
this.fps = this.frameCount;
347-
this.frameCount = 0;
348-
this.lastTime = currentTime;
349-
this.updateStats();
350-
}
351-
352325
// Update simulation at target FPS
353326
const targetInterval = 1000 / this.targetFPS;
354327
if (currentTime - this.lastUpdateTime >= targetInterval) {
@@ -400,11 +373,6 @@ class EvolutionApp {
400373
this.camera.y
401374
);
402375
}
403-
404-
updateStats() {
405-
this.updateSeedDisplay();
406-
}
407-
408376
showError(message) {
409377
const errorDiv = document.createElement("div");
410378
errorDiv.style.cssText = `

0 commit comments

Comments
 (0)