17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-05 14:24:51 +01:00

Steady the volumetric fog and add a switch for the old headlight beams

This commit is contained in:
2026-10-16 23:23:51 +02:00
parent 8b929fc1da
commit 6ee628aaa5
9 changed files with 114 additions and 32 deletions

View File

@@ -8,6 +8,29 @@
layout(binding = FOG_VOLUME_TEX) uniform sampler3D fog_volume;
// the volume at a point of the view (0-1) and a coordinate along the slices, filtered across the view with a cubic B-spline
// (four fetches of the linear filter): a cell is several pixels wide, and the linear filter alone draws the shafts of light and
// the edges of shadows in the fog as steps
vec4 fog_volume_at(vec2 coords, float slice)
{
vec2 size = vec2(textureSize(fog_volume, 0).xy);
vec2 texel = coords * size - 0.5;
vec2 base = floor(texel);
vec2 f = texel - base;
vec2 f2 = f * f;
vec2 f3 = f2 * f;
vec2 w0 = (1.0 - 3.0 * f + 3.0 * f2 - f3) / 6.0;
vec2 w1 = (4.0 - 6.0 * f2 + 3.0 * f3) / 6.0;
vec2 w2 = (1.0 + 3.0 * f + 3.0 * f2 - 3.0 * f3) / 6.0;
vec2 w3 = f3 / 6.0;
vec2 g0 = w0 + w1;
vec2 g1 = w2 + w3;
vec2 h0 = (base - 0.5 + w1 / g0) / size;
vec2 h1 = (base + 1.5 + w3 / g1) / size;
return g0.y * (g0.x * textureLod(fog_volume, vec3(h0.x, h0.y, slice), 0.0) + g1.x * textureLod(fog_volume, vec3(h1.x, h0.y, slice), 0.0))
+ g1.y * (g0.x * textureLod(fog_volume, vec3(h0.x, h1.y, slice), 0.0) + g1.x * textureLod(fog_volume, vec3(h1.x, h1.y, slice), 0.0));
}
// rgb: light the fog adds, a: what it lets through
vec4 fog_along_view(vec3 view, vec2 fragcoord)
{
@@ -17,16 +40,16 @@ vec4 fog_along_view(vec3 view, vec2 fragcoord)
vec3 direction = mat3(inv_view) * (view / span_distance);
if (fog_volume_params.x < 0.5)
return fog_analytic(direction, 0.0, span_distance, false);
// slices are spaced exponentially in the view depth; slice k holds the fog up to its far side
// slices are spaced exponentially in the view depth plus FOG_VOLUME_BIAS; slice k holds the fog up to its far side
float depth = max(-view.z, 1e-4);
float slices = fog_volume_params.w;
float slice = log(max(depth / fog_volume_params.y, 1e-6)) * fog_volume_params.z;
float slice = log(max((depth + FOG_VOLUME_BIAS) / (fog_volume_params.y + FOG_VOLUME_BIAS), 1e-6)) * fog_volume_params.z;
vec2 coords = fragcoord * fog_volume_target.xy;
if (slice < 1.0)
return mix(vec4(0.0, 0.0, 0.0, 1.0), textureLod(fog_volume, vec3(coords, 0.5 / slices), 0.0), max(slice, 0.0));
return mix(vec4(0.0, 0.0, 0.0, 1.0), fog_volume_at(coords, 0.5 / slices), max(slice, 0.0));
if (slice < slices)
return textureLod(fog_volume, vec3(coords, (slice - 0.5) / slices), 0.0);
vec4 volume = textureLod(fog_volume, vec3(coords, (slices - 0.5) / slices), 0.0);
return fog_volume_at(coords, (slice - 0.5) / slices);
vec4 volume = fog_volume_at(coords, (slices - 0.5) / slices);
vec4 rest = fog_analytic(direction, fog_volume_target.z * span_distance / depth, span_distance, false);
return vec4(volume.rgb + volume.a * rest.rgb, volume.a * rest.a);
}
@@ -40,7 +63,7 @@ vec4 fog_sky(vec3 viewdirection, vec2 fragcoord)
if (fog_volume_params.x < 0.5 || view.z > -1e-3)
return fog_analytic(direction, 0.0, 200000.0, true);
float slices = fog_volume_params.w;
vec4 volume = textureLod(fog_volume, vec3(fragcoord * fog_volume_target.xy, (slices - 0.5) / slices), 0.0);
vec4 volume = fog_volume_at(fragcoord * fog_volume_target.xy, (slices - 0.5) / slices);
vec4 rest = fog_analytic(direction, fog_volume_target.z / -view.z, 200000.0, true);
return vec4(volume.rgb + volume.a * rest.rgb, volume.a * rest.a);
}