rusting_engine 2.7.0

Vulkan 3D game engine with GPU-accelerated physics for massive physics-heavy scenes
// Rusting shader packs, version 1: the built-ins a `#rusting composite 1`
// pass sees. A composite pass runs over the whole HDR image before bloom;
// fields are only ever added at the end.
struct CompositeInput {
    // 0..1 across the image, (0, 0) at the top left.
    vec2 uv;
    // This pass's pixel, (0, 0) at the top left.
    ivec2 pixel;
    // One over this pass's target size in pixels.
    vec2 texel;
    // Seconds since start, the same as `frame.time.x`.
    float time;
};
// Linear HDR color at uv: the scene, or the output of the last full-size
// composite pass before this one.
vec4 color_at(vec2 uv) {
    return textureLod(chain, uv, 0.0);
}
// Stored depth at uv: 0 at the near plane, 1 at the far plane or the sky.
float depth_at(vec2 uv) {
    return textureLod(scene_depth, uv, 0.0).r;
}
// Camera-space position of the surface at uv (the camera looks down -z).
vec3 view_position_at(vec2 uv) {
    vec4 position = frame.inverse_projection
        * vec4(uv * 2.0 - 1.0, depth_at(uv), 1.0);
    return position.xyz / position.w;
}
// World position of the surface at uv.
vec3 world_position_at(vec2 uv) {
    return (frame.inverse_view * vec4(view_position_at(uv), 1.0)).xyz;
}
// World normal of the surface at uv, rebuilt from the depth of the pixels
// around it and facing the camera.
vec3 normal_at(vec2 uv) {
    vec2 texel = frame.screen.zw;
    vec3 center = world_position_at(uv);
    vec3 right = world_position_at(uv + vec2(texel.x, 0.0)) - center;
    vec3 left = center - world_position_at(uv - vec2(texel.x, 0.0));
    vec3 down = world_position_at(uv + vec2(0.0, texel.y)) - center;
    vec3 up = center - world_position_at(uv - vec2(0.0, texel.y));
    // The shorter difference stays on this surface at an edge.
    vec3 dx = dot(right, right) < dot(left, left) ? right : left;
    vec3 dy = dot(down, down) < dot(up, up) ? down : up;
    vec3 normal = normalize(cross(dy, dx));
    return dot(normal, frame.camera_position.xyz - center) < 0.0
        ? -normal
        : normal;
}
// Last frame's result of the composite chain at uv. The engine keeps this
// image only for packs whose files call history_at.
vec4 history_at(vec2 uv) {
    return textureLod(history, uv, 0.0);
}
// 1 where the shadowed light reaches world_position, 0 in its shadow; one
// tap of the shadow map, so move the point a little off its surface.
float shadow_at(vec3 world_position) {
    int count = int(shadow.cascade_info.x);
    int tiles = int(shadow.cascade_info.y);
    if (count == 0) {
        return 1.0;
    }
    int cascade = 0;
    float fade = 0.0;
    if (shadow.cascade_info.z > 0.5) {
        vec3 away = world_position - shadow.cascade_forward.xyz;
        vec3 size = abs(away);
        if (size.x >= size.y && size.x >= size.z) {
            cascade = away.x > 0.0 ? 0 : 1;
        } else if (size.y >= size.z) {
            cascade = away.y > 0.0 ? 2 : 3;
        } else {
            cascade = away.z > 0.0 ? 4 : 5;
        }
    } else {
        float depth = dot(world_position, shadow.cascade_forward.xyz)
            - shadow.cascade_forward.w;
        while (cascade < count - 1 && depth > shadow.cascade_far[cascade]) {
            cascade += 1;
        }
        if (depth > shadow.cascade_far[count - 1]) {
            return 1.0;
        }
        // Fades out over the last fifth of the reach, like the scene's.
        float reach = shadow.cascade_far[count - 1];
        fade = smoothstep(reach * 0.8, reach, depth);
    }
    vec4 clip = shadow.cascades[cascade] * vec4(world_position, 1.0);
    if (clip.w <= 0.0) {
        return 1.0;
    }
    vec3 coords = clip.xyz / clip.w;
    if (coords.z > 1.0) {
        return 1.0;
    }
    vec2 texel = float(tiles) / vec2(textureSize(shadow_map, 0));
    vec2 uv = clamp(coords.xy * 0.5 + 0.5, texel * 0.5, 1.0 - texel * 0.5);
    vec2 tile = vec2(cascade % tiles, cascade / tiles);
    return mix(texture(shadow_map, vec3((tile + uv) / float(tiles), coords.z)), 1.0, fade);
}
// Output of composite pass k (0 is the first in the pack's list) at uv.
// Only passes before this one have run; the others read black.
vec4 composite_at(int k, vec2 uv) {
    return textureLod(composite_targets[k], uv, 0.0);
}
#ifndef RUSTING_CUSTOM_COMPOSITE
void composite(CompositeInput i, inout vec4 color) {}
#endif