From 0f33d80fd3c0a9956c6f69268273eb4cbe249e5b Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 14 Jul 2026 23:55:17 +0800 Subject: [PATCH] shader: gaussian-speck stars + star_aa toggle + bloom/exposure uniforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit star_color's smoothstep(0.5,0.0,d) with scale=80 produced blocky rectangles at low render_scale. Replace with a gaussian speck: distance to cell center with exp(-d²/r²) falloff, producing a round 2-3 pixel anti-aliased disk. star_aa uniform toggles between the gaussian path (desktop default) and the old square-cell fast path (web default). Also adds bloom_threshold/bloom_strength/exposure uniform fields to BlackHoleUniforms (used by later bloom tasks) with safe defaults. --- assets/shaders/black_hole.wgsl | 26 +++++++++++++++++++++----- src/params.rs | 9 +++++++++ src/render/material.rs | 8 ++++++++ src/render/plugin.rs | 4 ++++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/assets/shaders/black_hole.wgsl b/assets/shaders/black_hole.wgsl index 1294240..1b7c60d 100644 --- a/assets/shaders/black_hole.wgsl +++ b/assets/shaders/black_hole.wgsl @@ -34,6 +34,10 @@ struct BlackHoleUniforms { planet_count: u32, steps: u32, spin: f32, + star_aa: u32, + bloom_threshold: f32, + bloom_strength: f32, + exposure: f32, _pad5: f32, }; @@ -82,16 +86,28 @@ fn hash13(p: vec3) -> f32 { fn star_color(dir: vec3, intensity: f32) -> vec3 { let scale = 80.0; - let cell = floor(dir * scale); + let p = dir * scale; + let cell = floor(p); let h = hash13(cell); let threshold = 0.985; if (h > threshold) { let b = (h - threshold) / (1.0 - threshold); let col = mix(vec3(0.6, 0.7, 1.0), vec3(1.0, 0.9, 0.7), b); - let f = abs(dir * scale - cell); - let d = max(f.x, max(f.y, f.z)); - let falloff = smoothstep(0.5, 0.0, d); - return col * b * falloff * 3.0 * intensity; + if (uniforms.star_aa != 0u) { + // Gaussian speck: distance to cell center, soft radial falloff. + // Produces a round 2-3 pixel anti-aliased disk instead of a square. + let center = cell + vec3(0.5); + let dist = length(p - center); + let radius = 0.25 + b * 0.4; + let falloff = exp(-dist * dist / (radius * radius)); + return col * b * falloff * 4.0 * intensity; + } else { + // Original fast path: square-cell smoothstep (blocky but cheap). + let f = abs(p - cell); + let d = max(f.x, max(f.y, f.z)); + let falloff = smoothstep(0.5, 0.0, d); + return col * b * falloff * 3.0 * intensity; + } } return vec3(0.0); } diff --git a/src/params.rs b/src/params.rs index a469e32..251dd75 100644 --- a/src/params.rs +++ b/src/params.rs @@ -27,6 +27,11 @@ pub struct BlackHoleParams { pub planet_count: u32, // Kerr (Phase 2; unused in Phase 1) pub spin: f32, + // Quality (Phase 3: cinematic rendering) + pub star_aa: bool, + pub bloom_threshold: f32, + pub bloom_strength: f32, + pub exposure: f32, } impl Default for BlackHoleParams { @@ -48,6 +53,10 @@ impl Default for BlackHoleParams { skybox_intensity: 0.0, // procedural stars only by default planet_count: 0, spin: 0.0, + star_aa: if cfg!(target_arch = "wasm32") { false } else { true }, + bloom_threshold: 1.0, + bloom_strength: 0.8, + exposure: 1.0, } } } diff --git a/src/render/material.rs b/src/render/material.rs index 8bb24b9..79d0065 100644 --- a/src/render/material.rs +++ b/src/render/material.rs @@ -38,6 +38,10 @@ pub struct BlackHoleUniforms { pub planet_count: u32, pub steps: u32, pub spin: f32, // Phase 2: dimensionless Kerr spin χ = a/M ∈ [0,1]. + pub star_aa: u32, + pub bloom_threshold: f32, + pub bloom_strength: f32, + pub exposure: f32, pub _pad5: f32, } @@ -70,6 +74,10 @@ impl Default for BlackHoleUniforms { planet_count: 0, steps: 300, spin: 0.0, + star_aa: 1, + bloom_threshold: 1.0, + bloom_strength: 0.8, + exposure: 1.0, _pad5: 0.0, } } diff --git a/src/render/plugin.rs b/src/render/plugin.rs index 83ae62d..8ee6f29 100644 --- a/src/render/plugin.rs +++ b/src/render/plugin.rs @@ -261,5 +261,9 @@ fn mirror_params( u.planet_count = params.planet_count; u.steps = params.steps; u.spin = params.spin; + u.star_aa = params.star_aa as u32; + u.bloom_threshold = params.bloom_threshold; + u.bloom_strength = params.bloom_strength; + u.exposure = params.exposure; } }