Merge commit '329439c' into lang/foundations

This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 17:00:53 +03:00
commit 8c598b18af
32 changed files with 36 additions and 14 deletions

View file

@ -11,7 +11,10 @@ function fog_casters(render3d_st: mut Render3dState, l: Layer) -> int {
if w <= 0.0 { return l.sh_buf }
let dx = render3d_st.cam_pos[0] - l.fog_x
let dz = render3d_st.cam_pos[2] - l.fog_z
if l.fog_wall == w and l.fog_src == l.n_sh and dx * dx + dz * dz < FOG_CAST_STEP * FOG_CAST_STEP { return l.fog_buf }
if l.fog_wall == w and l.fog_src == l.n_sh and (l.fog_all or dx * dx + dz * dz < FOG_CAST_STEP * FOG_CAST_STEP) {
if l.fog_all { return l.sh_buf }
return l.fog_buf
}
l.fog_wall = w; l.fog_src = l.n_sh
l.fog_x = render3d_st.cam_pos[0]; l.fog_z = render3d_st.cam_pos[2]
let far = w + R3D_FOG_MARGIN + FOG_CAST_THROW + FOG_CAST_STEP
@ -30,11 +33,15 @@ function fog_casters(render3d_st: mut Render3dState, l: Layer) -> int {
n += 1
}
l.fog_n = n
# a wall that keeps nearly the whole layer (a kilometre): the static list, and no rebuild as the camera
# moves - copying and uploading 60k cards every 4 m bought nothing there
l.fog_all = n * 5 >= total * 4
if l.fog_all { return l.sh_buf }
if n > 0 { gpu_buffer_upload(render3d_st, l.fog_buf, n * INST_FLOATS * 4, data_of(dst), GPU_DYNAMIC) }
return l.fog_buf
}
function fog_casters_n(render3d_st: Render3dState, l: Layer) -> int {
if render3d_st.r3d_fog_wall <= 0.0 { return l.n_sh }
if render3d_st.r3d_fog_wall <= 0.0 or l.fog_all { return l.n_sh }
return l.fog_n
}

View file

@ -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)

View file

@ -39,6 +39,7 @@ property Layer {
fog_buf: int = 0, # the casters inside the fog wall (fog_casters.ludic)
fog_n: int = 0,
fog_src: int = -1,
fog_all: bool = false, # the wall keeps (nearly) all of it: casters from sh_buf, no rebuild
fog_wall: float = 0.0,
fog_x: float = 0.0,
fog_z: float = 0.0,

View file

@ -319,7 +319,7 @@ vec3 applyFog(vec3 col, vec3 wpos, float dist) {
if (u_fog_wall > 0.0) {
// full by 0.85 of the wall, so whatever is cut at the wall is cut inside solid fog
float w = smoothstep(0.3 * u_fog_wall, 0.85 * u_fog_wall, dist);
col = mix(col, fogWallCol(dir), w);
if (w > 0.0) col = mix(col, fogWallCol(dir), w);
}
return col;
}

View file

@ -551,7 +551,7 @@ T 3e4b62f9 u_tershadow 8
T 3e4b62f9 u_tershadow_aux 9
T 3e4b62f9 u_ts_height 10
P 676965ab fullscreen.vert ssgi.frag
B 676965ab frag 1 984
B 676965ab frag 1 1000
U 676965ab frag u_cascade_vp 0 mat4 5 64
U 676965ab frag u_cascade_split 320 float 5 16
U 676965ab frag u_cascade_range 400 float 5 16
@ -588,13 +588,14 @@ U 676965ab frag u_time 816 float 1 0
U 676965ab frag u_fog_inscatter 820 float 1 0
U 676965ab frag u_fog_desat 824 float 1 0
U 676965ab frag u_fog_wall 828 float 1 0
U 676965ab frag u_inv_proj 832 mat4 1 0
U 676965ab frag u_proj 896 mat4 1 0
U 676965ab frag u_texel 960 vec2 1 0
U 676965ab frag u_radius 968 float 1 0
U 676965ab frag u_intensity 972 float 1 0
U 676965ab frag u_contact 976 float 1 0
U 676965ab frag u_frame 980 float 1 0
U 676965ab frag u_ao_far 832 float 1 0
U 676965ab frag u_inv_proj 848 mat4 1 0
U 676965ab frag u_proj 912 mat4 1 0
U 676965ab frag u_texel 976 vec2 1 0
U 676965ab frag u_radius 984 float 1 0
U 676965ab frag u_intensity 988 float 1 0
U 676965ab frag u_contact 992 float 1 0
U 676965ab frag u_frame 996 float 1 0
T 676965ab u_brdf 2
T 676965ab u_depth 3
T 676965ab u_irradiance 4

View file

@ -2,6 +2,7 @@
// frame's lit colour; half resolution, denoised over time by the TAA history it feeds
in vec2 v_uv;
out vec4 o_color;
uniform float u_ao_far;
uniform sampler2D u_depth;
uniform sampler2D u_prev_color; // last frame's anti-aliased HDR colour
uniform mat4 u_inv_proj;
@ -18,7 +19,8 @@ vec3 viewPos(vec2 uv) {
}
void main() {
vec3 P = viewPos(v_uv);
if (-P.z > 900.0) { o_color = vec4(0.0, 0.0, 0.0, 1.0); return; }
// past 900 m, or where a fog wall has already hidden everything (u_ao_far, post.ludic)
if (-P.z > (u_ao_far > 0.0 ? u_ao_far : 900.0)) { o_color = vec4(0.0, 0.0, 0.0, 1.0); return; }
vec3 Pr = viewPos(v_uv + vec2(u_texel.x, 0.0)), Pl = viewPos(v_uv - vec2(u_texel.x, 0.0));
vec3 Pu = viewPos(v_uv + vec2(0.0, u_texel.y)), Pd = viewPos(v_uv - vec2(0.0, u_texel.y));
vec3 dx = (abs(Pr.z - P.z) < abs(P.z - Pl.z)) ? Pr - P : P - Pl;