mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-18 14:59:19 +02:00
53 lines
2.7 KiB
Plaintext
53 lines
2.7 KiB
Plaintext
// the fog volume of the main view, second pass: the light and extinction of the cells (fog_inject.comp) added up along the rays
|
|
// of the view, front to back, into what the fog adds and lets through from the camera to the far side of every slice
|
|
// (apply_fog.glsl). the light of a cell is integrated over its length as Hillaire (2015) does it, so it doesn't grow with
|
|
// the size of the cell. the light of the cells is taken with the light of their neighbours across the view, a 3x3 tent filter
|
|
// (four fetches of the linear filter): every cell is sampled at a point of its own in a frame, and what is left of that after
|
|
// the blending over frames differs from cell to cell, which the filter evens out. the history keeps the cells unfiltered
|
|
|
|
#include <common>
|
|
|
|
layout(local_size_x = WEATHER_GROUP_SIZE, local_size_y = WEATHER_GROUP_SIZE, local_size_z = 1) in;
|
|
|
|
layout(binding = CLOUD_HISTORY_TEX) uniform sampler3D fog_scattering;
|
|
layout(rgba16f, binding = 0) uniform writeonly image3D fog_integrated;
|
|
|
|
layout(location = 0) uniform ivec3 grid;
|
|
layout(location = 1) uniform mat4 inverse_projection;
|
|
// x: near, y: far, z: slices / log((far + FOG_VOLUME_BIAS) / (near + FOG_VOLUME_BIAS))
|
|
layout(location = 3) uniform vec4 slicing;
|
|
|
|
void main()
|
|
{
|
|
ivec2 column = ivec2(gl_GlobalInvocationID.xy);
|
|
if (any(greaterThanEqual(column, grid.xy)))
|
|
return;
|
|
vec2 coords = (vec2(column) + 0.5) / vec2(grid.xy);
|
|
vec4 near = inverse_projection * vec4(coords * 2.0 - 1.0, 1.0, 1.0);
|
|
vec3 ray = near.xyz / near.w;
|
|
// metres along the ray per metre of the depth
|
|
float stretch = length(ray / -ray.z);
|
|
|
|
vec3 light = vec3(0.0);
|
|
float transmittance = 1.0;
|
|
float front = slicing.x;
|
|
for (int slice = 0; slice < grid.z; slice++)
|
|
{
|
|
float back = (slicing.x + FOG_VOLUME_BIAS) * exp(float(slice + 1) / slicing.z) - FOG_VOLUME_BIAS;
|
|
float span = (back - front) * stretch;
|
|
front = back;
|
|
vec4 cell = texelFetch(fog_scattering, ivec3(column, slice), 0);
|
|
float depthcoord = (float(slice) + 0.5) / float(grid.z);
|
|
vec2 texel = 1.0 / vec2(grid.xy);
|
|
cell.rgb = 0.25 * (textureLod(fog_scattering, vec3(coords + vec2(-0.5, -0.5) * texel, depthcoord), 0.0).rgb
|
|
+ textureLod(fog_scattering, vec3(coords + vec2(0.5, -0.5) * texel, depthcoord), 0.0).rgb
|
|
+ textureLod(fog_scattering, vec3(coords + vec2(-0.5, 0.5) * texel, depthcoord), 0.0).rgb
|
|
+ textureLod(fog_scattering, vec3(coords + vec2(0.5, 0.5) * texel, depthcoord), 0.0).rgb);
|
|
float extinction = max(cell.a, 1e-7);
|
|
float through = exp(-extinction * span);
|
|
light += transmittance * cell.rgb * ((1.0 - through) / extinction);
|
|
transmittance *= through;
|
|
imageStore(fog_integrated, ivec3(column, slice), vec4(light, transmittance));
|
|
}
|
|
}
|