feat(render): volumetric disk integration in the RK45 loop
Restructures the disk block in the main loop: - Off tier: flat disk_color_flat single midplane sample (old behavior). - Volumetric tiers: (A) in-slab per-step sampling accumulates emission × arc length, reusing the RK45 adaptive step density; (B) midplane edge- capture weights one at-plane sample by slab depth along the ray. Removes the Task-5 disk_color shim. physics.rs untouched; cargo test green.
This commit is contained in:
parent
107fbd0a74
commit
e2e2469971
@ -311,11 +311,6 @@ fn disk_color_flat(pos: vec3<f32>, dir: vec3<f32>) -> DiskSample {
|
|||||||
return DiskSample(vec3<f32>(col), 0.85);
|
return DiskSample(vec3<f32>(col), 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEMPORARY shim — removed in Task 7 when the main loop is restructured.
|
|
||||||
fn disk_color(pos: vec3<f32>, dir: vec3<f32>) -> vec3<f32> {
|
|
||||||
return disk_color_flat(pos, dir).color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volumetric disk color: ridged filaments drive brightness, a smoothstep-
|
// Volumetric disk color: ridged filaments drive brightness, a smoothstep-
|
||||||
// gated FBM drives density clumping, and a logarithmic-spiral term (riding
|
// gated FBM drives density clumping, and a logarithmic-spiral term (riding
|
||||||
// the Keplerian shear `rot`) drives large-scale arm structure. The three
|
// the Keplerian shear `rot`) drives large-scale arm structure. The three
|
||||||
@ -553,13 +548,41 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disk_hit(prev, new_pos)) {
|
// --- volumetric disk ---
|
||||||
let ty = prev.y / (prev.y - new_pos.y);
|
if (uniforms.disk_quality == 0u) {
|
||||||
let hit = mix(prev, new_pos, vec3<f32>(ty));
|
// Off tier: zero-thickness single midplane sample, fixed alpha.
|
||||||
let dc = disk_color(hit, new_dir);
|
if (disk_hit(prev, new_pos)) {
|
||||||
let a = 0.85;
|
let ty = prev.y / (prev.y - new_pos.y);
|
||||||
accum_color += (1.0 - accum_alpha) * dc * a;
|
let hit = mix(prev, new_pos, vec3<f32>(ty));
|
||||||
accum_alpha += (1.0 - accum_alpha) * a;
|
let s = disk_color_flat(hit, new_dir);
|
||||||
|
accum_color += (1.0 - accum_alpha) * s.color * s.density;
|
||||||
|
accum_alpha += (1.0 - accum_alpha) * s.density;
|
||||||
|
if (accum_alpha > 0.99) { break; }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Volumetric tier.
|
||||||
|
// (A) In-slab per-step sampling: if this step ends inside the
|
||||||
|
// thickness slab, accumulate emission × arc length. Reuses the
|
||||||
|
// RK45 adaptive step — dense where light bends, sparse where straight.
|
||||||
|
let slab_r = r_of(new_pos);
|
||||||
|
if (abs(new_pos.y) < uniforms.disk_half_thickness
|
||||||
|
&& slab_r >= uniforms.disk_inner
|
||||||
|
&& slab_r <= uniforms.disk_outer) {
|
||||||
|
let s = disk_color_volumetric(new_pos, new_dir);
|
||||||
|
let step_len = length(new_pos - prev);
|
||||||
|
accum_color += (1.0 - accum_alpha) * s.color * s.density * step_len;
|
||||||
|
accum_alpha += (1.0 - accum_alpha) * s.density * step_len;
|
||||||
|
}
|
||||||
|
// (B) Midplane edge-capture: if a step straddles y=0, add one
|
||||||
|
// precise at-plane sample weighted by the slab depth along the ray.
|
||||||
|
if (disk_hit(prev, new_pos)) {
|
||||||
|
let ty = prev.y / (prev.y - new_pos.y);
|
||||||
|
let hit = mix(prev, new_pos, vec3<f32>(ty));
|
||||||
|
let s = disk_color_volumetric(hit, new_dir);
|
||||||
|
let thickness_proj = uniforms.disk_half_thickness / max(abs(new_dir.y), 1e-3);
|
||||||
|
accum_color += (1.0 - accum_alpha) * s.color * s.density * thickness_proj;
|
||||||
|
accum_alpha += (1.0 - accum_alpha) * s.density * thickness_proj;
|
||||||
|
}
|
||||||
if (accum_alpha > 0.99) { break; }
|
if (accum_alpha > 0.99) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user