mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 22:39:19 +02:00
66 lines
2.6 KiB
Plaintext
66 lines
2.6 KiB
Plaintext
// the clouds of the main view smoothed over frames: the image of this frame (clouds_march.comp, ray started at another
|
|
// distance every frame) blended into the one of the previous frames, found where the clouds were by the distance of the
|
|
// clouds, the rotation and the move of the camera. the history is held to the range of the neighbourhood of this frame,
|
|
// so moving clouds and a turning camera don't leave trails
|
|
|
|
#include <common>
|
|
|
|
layout(local_size_x = WEATHER_GROUP_SIZE, local_size_y = WEATHER_GROUP_SIZE, local_size_z = 1) in;
|
|
|
|
layout(binding = CLOUD_TEX) uniform sampler2D current_color;
|
|
layout(binding = CLOUD_SHAPE_TEX) uniform sampler2D current_depth;
|
|
layout(binding = CLOUD_HISTORY_TEX) uniform sampler2D history_color;
|
|
layout(rgba16f, binding = 0) uniform writeonly image2D result;
|
|
|
|
layout(location = 1) uniform ivec2 size;
|
|
layout(location = 2) uniform mat4 inverse_projection;
|
|
layout(location = 3) uniform mat4 view_to_world;
|
|
// world axes to the clip space of the previous frame, the camera of the previous frame at the origin
|
|
layout(location = 4) uniform mat4 previous_projection_view;
|
|
// where the camera was in the previous frame, relative to where it is (world, metres)
|
|
layout(location = 5) uniform vec3 previous_camera;
|
|
// share of this frame in the result; 1 when there is no history
|
|
layout(location = 6) uniform float blend;
|
|
|
|
void main()
|
|
{
|
|
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
|
if (any(greaterThanEqual(texel, size)))
|
|
return;
|
|
vec4 current = texelFetch(current_color, texel, 0);
|
|
if (blend >= 1.0)
|
|
{
|
|
imageStore(result, texel, current);
|
|
return;
|
|
}
|
|
// the range of the neighbourhood
|
|
vec4 low = current;
|
|
vec4 high = current;
|
|
for (int y = -1; y <= 1; y++)
|
|
for (int x = -1; x <= 1; x++)
|
|
{
|
|
vec4 neighbour = texelFetch(current_color, clamp(texel + ivec2(x, y), ivec2(0), size - 1), 0);
|
|
low = min(low, neighbour);
|
|
high = max(high, neighbour);
|
|
}
|
|
vec2 ndc = (vec2(texel) + 0.5) / vec2(size) * 2.0 - 1.0;
|
|
vec4 near = inverse_projection * vec4(ndc, 1.0, 1.0);
|
|
vec3 direction = normalize(mat3(view_to_world) * normalize(near.xyz / near.w));
|
|
float span_distance = texelFetch(current_depth, texel, 0).r;
|
|
vec3 position = direction * span_distance - previous_camera;
|
|
vec4 clip = previous_projection_view * vec4(position, 1.0);
|
|
float share = blend;
|
|
vec4 history = current;
|
|
if (clip.w > 0.0)
|
|
{
|
|
vec2 coords = clip.xy / clip.w * 0.5 + 0.5;
|
|
if (all(greaterThanEqual(coords, vec2(0.0))) && all(lessThanEqual(coords, vec2(1.0))))
|
|
history = clamp(textureLod(history_color, coords, 0.0), low, high);
|
|
else
|
|
share = 1.0;
|
|
}
|
|
else
|
|
share = 1.0;
|
|
imageStore(result, texel, mix(history, current, share));
|
|
}
|