rusting_engine 2.7.0

Vulkan 3D game engine with GPU-accelerated physics for massive physics-heavy scenes
#version 450
// Rusting shader packs, version 1: the cloud layer. A pack's `clouds`
// program with `"scale": 0.5` or `0.25` runs here at that fraction of the
// screen instead of inline in sky.frag; sky.frag then puts the layer over
// the sky before fog: `sky * layer.a + layer.rgb`. Fields are only ever
// added at the end of CloudLayerInput.
#define RUSTING_CLOUD_LAYER 1
layout(location = 0) out vec4 out_layer;
// The scene's ambient hemisphere, for sky_lut_lod without a map.
layout(push_constant) uniform CloudLayerCamera {
    vec4 ambient;
    vec4 ground_ambient;
} camera;
// The scene's shadow upload, laid out as in sky.frag; only `environment`
// and `sky` are read.
layout(set = 0, binding = 1) readonly buffer Shadow {
    vec4 environment;
    vec4 scene_color;
    vec4 viewport;
    vec4 probes[8];
    mat4 inverse_view_projection;
    vec4 fog;
    vec4 fog_shape;
    vec4 ambient_occlusion;
    mat4 cascades[6];
    vec4 cascade_far;
    vec4 cascade_forward;
    vec4 cascade_info;
    vec4 cluster_view;
    vec4 cluster_depth;
    vec4 fog_shafts;
    mat4 fog_volumes[8];
    vec4 fog_volume_colors[8];
    vec4 sky[4];
} shadow;
layout(set = 0, binding = 2) uniform sampler2D environment_map;
layout(set = 0, binding = 3) uniform sampler2D cloud_layer_previous;
// Tiling 3D cloud noise, 64^3 RGBA8, repeat and linear (cloud_layer.rs).
layout(set = 0, binding = 4) uniform sampler3D cloud_noise_map;
#include "frame.glsl"
#include "sky_access.glsl"
// What the engine knows about the layer texel before the hook runs.
struct CloudLayerInput {
    // Unit world-space direction through the texel centre.
    vec3 direction;
    // Seconds since start, the same as SkyInput.time.
    float time;
    // Texel centre, 0..1, oriented as composite uv.
    vec2 uv;
    // 1 / layer size in texels.
    vec2 texel;
};
// Last frame's layer at `uv`, bilinear and clamped; vec4(0, 0, 0, 1) on
// the first frame and after a resize.
vec4 cloud_layer_history(vec2 uv) {
    return textureLod(cloud_layer_previous, clamp(uv, 0.0, 1.0), 0.0);
}
// Where `direction`, a point at infinity, was in last frame's layer: the
// camera's rotation only. Off 0..1 when it was behind or off screen.
vec2 cloud_layer_previous_uv(vec3 direction) {
    vec4 clip = frame.previous_view_projection * vec4(direction, 0.0);
    if (clip.w <= 1e-6) {
        return vec2(-1.0);
    }
    return clip.xy / clip.w * 0.5 + 0.5;
}
// The tiling cloud noise at `p`, one tile per unit: r Perlin-Worley (the
// base shape of Nubis-style clouds), g, b, a Worley fbm with 4, 8 and 16
// cells per tile, all 0..1, trilinear.
#define RUSTING_CLOUD_NOISE 1
vec4 cloud_noise(vec3 p) {
    return textureLod(cloud_noise_map, p, 0.0);
}
#include "cloud_layer_shader.glsl"
void main() {
    vec2 texel = 1.0 / vec2(textureSize(cloud_layer_previous, 0));
    vec2 uv = gl_FragCoord.xy * texel;
    vec2 ndc = uv * 2.0 - 1.0;
    vec4 near = frame.inverse_view * (frame.inverse_projection * vec4(ndc, 0.0, 1.0));
    vec4 far = frame.inverse_view * (frame.inverse_projection * vec4(ndc, 0.5, 1.0));
    vec3 direction = normalize(far.xyz / far.w - near.xyz / near.w);
    vec4 layer = vec4(0.0, 0.0, 0.0, 1.0);
    cloud_layer(CloudLayerInput(direction, camera.ambient.w, uv, texel), layer);
    out_layer = vec4(max(layer.rgb, vec3(0.0)), clamp(layer.a, 0.0, 1.0));
}