rusting_engine 2.7.0

Vulkan 3D game engine with GPU-accelerated physics for massive physics-heavy scenes
#version 450
layout(location = 0) in vec3 position;
#if defined(RUSTING_VERTEX_INPUTS) || defined(RUSTING_SHADOW_MASK)
// Only a shader pack's vertex hook and alpha-tested casters read the rest
// of the vertex; the engine defines these when it adds one.
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv;
layout(location = 5) in vec4 color;
layout(location = 6) in uint data;
#endif
#ifdef RUSTING_SHADOW_MASK
// Alpha-tested casters: shadow.frag cuts the holes of Mask materials with
// the uv and alpha the scene pass uses.
layout(location = 0) out vec2 v_uv;
layout(location = 1) out float v_alpha;
layout(location = 2) flat out float v_cutoff;
#endif
layout(push_constant) uniform Camera {
    mat4 view_projection;
    vec4 eye;
    vec4 ambient;
    vec4 ground_ambient;
    uvec4 light_info;
} camera;
struct PhysicsState {
    mat4 model;
    vec4 velocity;
    vec4 angular_velocity;
    vec4 properties;
    vec4 custom_values;
    uvec4 metadata;
};
layout(set = 0, binding = 0) readonly buffer PhysicsStates {
    PhysicsState data[];
} physics_states;
struct RenderInstance {
    mat4 model;
    mat3x4 normal;
    vec4 color;
    vec4 emissive;
    vec4 surface;
    uvec4 physics;
    vec4 transmission;
    vec4 uv_transform;
    vec4 splat_scale;
    vec4 water;
};
layout(set = 0, binding = 1) readonly buffer RenderInstances {
    RenderInstance data[];
} render_instances;
// Wind sway: `Foliage` copies and swaying materials carry their lean per
// unit of wind in normal[0].w, a gust frequency in normal[1].w and a bend
// height in normal[2].w, and bend by the force fields at their base, as
// `lean_matrix` on the CPU did.
#define NO_BODY_SHAPES
#include <physics_shapes.glsl>
#include <physics_fields.glsl>
vec2 foliage_lean(float sway, float frequency, vec3 base, float seconds) {
    if (sway <= 0.0) return vec2(0.0);
    vec3 push = field_push(base, 0.001, uint(force_fields.data.length()), seconds);
    vec2 lean = push.xz * sway;
    if (frequency > 0.0) {
        // Gusts, phased by position so neighbours do not move together.
        float phase = dot(base.xz, vec2(0.37, 0.61));
        lean *= 1.0 + 0.5 * sin(6.2831853 * frequency * seconds + phase);
    }
    // Past 45 degrees a copy would stretch more than it leans.
    float size = length(lean);
    return size > 1.0 ? lean / size : lean;
}
// Sideways reach per unit of lean at `y` above the base, and its slope.
// With a bend height the base stays rooted: y^2 / 2h curves up to slope 1
// at h, then runs straight. Without one the whole mesh shears.
vec2 sway_bend(float y, float height) {
    if (height <= 0.0) return vec2(y, 1.0);
    if (y <= 0.0) return vec2(0.0);
    return y < height ? vec2(y * y / (2.0 * height), y / height) : vec2(y - 0.5 * height, 1.0);
}
// The shader pack vertex hook; see vertex_hook.glsl.
#include "vertex_hook.glsl"
void main() {
    RenderInstance instance = render_instances.data[gl_InstanceIndex];
    if ((instance.physics.w & 1u) == 0u) {
        // Every vertex at one point: a zero-area triangle draws nothing.
        gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
        return;
    }
    mat4 model = instance.physics.x == 0xffffffffu
        ? instance.model
        : physics_states.data[instance.physics.x].model;
    vec4 world_position = model * vec4(position, 1.0);
    vec2 lean = foliage_lean(instance.normal[0].w, instance.normal[1].w, model[3].xyz, camera.ambient.w);
    world_position.xz += lean * sway_bend(world_position.y - model[3].y, instance.normal[2].w).x;
#ifdef RUSTING_SHADOW_MASK
    v_uv = uv * instance.uv_transform.xy + instance.uv_transform.zw;
    // Terrain splat weights are not coverage, as in scene.vert.
    bool splat = abs(instance.transmission.w - 1.0) < 0.5;
    v_alpha = splat ? 1.0 : instance.color.a * color.a;
    v_cutoff = uintBitsToFloat(instance.physics.z);
#endif
#ifdef RUSTING_CUSTOM_VERTEX
    vec3 world_normal = normalize(mat3(instance.normal) * normal);
    vec4 tinted = instance.color * color;
    VertexOutput o = VertexOutput(world_position.xyz, world_normal, tinted);
    vertex(VertexInput(position, world_position.xyz, world_normal,
        uv * instance.uv_transform.xy + instance.uv_transform.zw, tinted,
        data & 0xffffu, data & ~0xffffu, camera.ambient.w), o);
    world_position.xyz = o.world_position;
#ifdef RUSTING_SHADOW_MASK
    v_alpha = splat ? 1.0 : o.color.a;
#endif
#endif
    gl_Position = camera.view_projection * world_position;
}