feat(disk): tune volumetric disk noise for opaque body with visible streaks

This commit is contained in:
xfy 2026-07-15 16:59:49 +08:00
parent abdd50576b
commit a5ef427cb8
3 changed files with 23 additions and 5 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/target /target
/dist /dist
.zcode/ .zcode/
others/

View File

@ -387,7 +387,10 @@ fn disk_color_flat(pos: vec3<f32>, dir: vec3<f32>) -> DiskSample {
// faster than outer correct differential rotation. // faster than outer correct differential rotation.
let noise = disk_noise(vec3<f32>(pos.x * 0.3, pos.z * 0.3, rot), uniforms.time); let noise = disk_noise(vec3<f32>(pos.x * 0.3, pos.z * 0.3, rot), uniforms.time);
let col = disk_emission(r, pos, dir, 0.6 + 0.4 * noise); // Contrast-boosted, mean-preserving: low floor + high peak. The Keplerian
// flow (the `rot` z term above) reads as moving clumps rather than a flat
// glow, without dimming the disk (mean old 0.6 + 0.4·n 0.8).
let col = disk_emission(r, pos, dir, 0.2 + 1.6 * noise * noise);
return DiskSample(vec3<f32>(col), 0.85); return DiskSample(vec3<f32>(col), 0.85);
} }
@ -422,9 +425,18 @@ fn disk_color_volumetric(pos: vec3<f32>, dir: vec3<f32>) -> DiskSample {
let filament = ridged_fbm(sp * uniforms.filament_freq + warp * 1.5, let filament = ridged_fbm(sp * uniforms.filament_freq + warp * 1.5,
filament_octaves, uniforms.filament_sharpness); filament_octaves, uniforms.filament_sharpness);
// Layer 2: density clumping (soft ramp, no hard cut avoids patchiness). // Layer 2: density. The floor is HIGH on purpose: alpha accumulates from
// this field, so a low floor (the earlier 0.15 + 1.5·n² form) let noise
// valleys drop to ~0.28 and the disk became see-through there. Keeping the
// floor at ~0.55 ( the original 0.35+0.65·n valleys) keeps the disk solid
// and opaque. The rotation is NOT carried by density holes it is carried
// by the `brightness` filament term below, which is polar-sampled and
// rotates via the `+ rot` in `sp`. So: solid opacity here, moving streaks
// via brightness. The squaring only sharpens the mild clumping for a bit
// of thickness variation; it does not punch holes.
let density_noise = fbm3(sp * uniforms.density_freq + warp, density_octaves); let density_noise = fbm3(sp * uniforms.density_freq + warp, density_octaves);
let base_density = (0.35 + 0.65 * density_noise) * uniforms.density_strength; let clumped = density_noise * density_noise;
let base_density = (0.55 + 0.9 * clumped) * uniforms.density_strength;
// Layer 3: logarithmic-spiral arm modulation, advected by Keplerian shear. // Layer 3: logarithmic-spiral arm modulation, advected by Keplerian shear.
let arm_phase = phi * uniforms.arm_count + log(max(r, 0.1)) * uniforms.arm_tightness - rot; let arm_phase = phi * uniforms.arm_count + log(max(r, 0.1)) * uniforms.arm_tightness - rot;
@ -432,7 +444,12 @@ fn disk_color_volumetric(pos: vec3<f32>, dir: vec3<f32>) -> DiskSample {
let arm_mod = mix(1.0, pow(arm, 2.0), uniforms.arm_strength); let arm_mod = mix(1.0, pow(arm, 2.0), uniforms.arm_strength);
let total_density = base_density * arm_mod; let total_density = base_density * arm_mod;
let brightness = 0.5 + filament; // Filament (ridged) brightness the PRIMARY carrier of visible rotation.
// Polar-sampled (via `sp`), so the `+ rot` Keplerian term advects these
// bright/dim tangential streaks around the hole on a solid (opaque) disk.
// Wide contrast (0.1 1.9) so the sweeping streaks read clearly without
// needing see-through gaps.
let brightness = 0.1 + 1.8 * filament;
let col = disk_emission(r, pos, dir, brightness); let col = disk_emission(r, pos, dir, brightness);

View File

@ -134,7 +134,7 @@ impl Default for BlackHoleParams {
disk_outer: 15.0, disk_outer: 15.0,
disk_tilt: 0.45, // ~25.8 deg disk_tilt: 0.45, // ~25.8 deg
disk_brightness: 1.0, disk_brightness: 1.0,
disk_rotation_speed: 0.5, disk_rotation_speed: 1.2,
doppler_enabled: true, doppler_enabled: true,
doppler_strength: 1.0, doppler_strength: 1.0,
steps: if cfg!(target_arch = "wasm32") { 200 } else { 300 }, steps: if cfg!(target_arch = "wasm32") { 200 } else { 300 },