render3d: under a fog wall the volumetric air is marched only to it, SSGI stops where it is solid, and card casters that fill the wall stop rebuilding
The volumetric pass marched 800 m in a fixed number of steps whatever the wall: it now stops at the wall with steps in proportion (at least 8) - 0.57 -> 0.33 ms at 30 m by the pass timers. SSGI skipped only past 900 m; it now also skips past 0.85 of a wall, where the fog is solid (u_ao_far). applyFog samples the fog's colour only where its weight is above zero. A card layer whose casters inside the wall are 80% or more of it (a kilometre's wall) casts from its static list and is not refiltered and re-uploaded every 4 m of camera motion. Fog off: the frame unchanged (0 pixels over 8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5b3cfac48e
commit
329439cf61
32 changed files with 36 additions and 14 deletions
|
|
@ -235,6 +235,10 @@ function post_ssao_pass(render3d_st: mut Render3dState) -> void {
|
|||
u_f2(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_ao, "u_texel"), 1.0 / float(render3d_st.post_w), 1.0 / float(render3d_st.post_h))
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_ao, "u_radius"), render3d_st.post_ao_radius)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_ao, "u_intensity"), render3d_st.post_ao_intensity)
|
||||
# nothing to shade past where a fog wall is solid (0.85 of it)
|
||||
var ao_far = 900.0
|
||||
if render3d_st.r3d_fog_wall > 0.0 { ao_far = Math.min(ao_far, 0.85 * render3d_st.r3d_fog_wall) }
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_ao, "u_ao_far"), ao_far)
|
||||
var contact = render3d_st.post_contact
|
||||
if r3d_env_has(render3d_st, "R3D_NOCONTACT") { contact = 0.0 }
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_ao, "u_contact"), contact)
|
||||
|
|
@ -266,10 +270,17 @@ function post_volumetric_pass(render3d_st: mut Render3dState) -> void {
|
|||
u_v3(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_cam_pos"), render3d_st.cam_pos)
|
||||
u_v3(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_sun_dir"), render3d_st.sun_dir)
|
||||
u_v3(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_sun_color"), render3d_st.sun_color)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_steps"), render3d_st.post_vol_steps)
|
||||
# under a fog wall the air is marched only as far as it, with steps in proportion (at least 8)
|
||||
var vfar = render3d_st.post_vol_far
|
||||
var vsteps = render3d_st.post_vol_steps
|
||||
if render3d_st.r3d_fog_wall > 0.0 and render3d_st.r3d_fog_wall < vfar {
|
||||
vsteps = Math.max(8.0, Math.floor(vsteps * render3d_st.r3d_fog_wall / vfar))
|
||||
vfar = render3d_st.r3d_fog_wall
|
||||
}
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_steps"), vsteps)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_density"), render3d_st.post_vol_density)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_falloff"), render3d_st.post_vol_falloff)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_far"), render3d_st.post_vol_far)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_far"), vfar)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_g"), render3d_st.post_vol_g)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_mist"), render3d_st.post_vol_mist)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, render3d_st.post_p_vol, "u_vol_mist_h"), render3d_st.post_vol_mist_h)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue