Nimbin[12]?Games / Entropie / entropie/assets/shaders/scene.vert

Entropie git · main

Entropie festival game; first steps

sdl c game entropie cmake · first commit 2026-10-10 · last commit 2026-11-02 (19 hours ago) · synced 10 hours ago

C 88.5% Markdown 9.1% GLSL 2.3%
git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gz
entropie/assets/shaders/scene.vert 2.8 KB · 70 lines raw
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec3 aColor;

uniform mat4  model;             // rotation + translation only
uniform mat4  view;
uniform mat4  projection;
uniform mat4  lightSpaceMatrix;
uniform float boilTime;
uniform float terrainSize;  // > 0 only while drawing the terrain
uniform float grassDepth;
uniform float decalSize;    // > 0 for things lying on the ground: they sink with it
uniform float grass;        // > 0 while drawing grass blades (terrain size); aNormal.y = height above the ground
uniform sampler2D wearMap;  // 0 = meadow, 1 = trampled path
uniform sampler2D waterMap; // soil moisture, standing water, pee, mud (world/wetness.h)

out vec3  WorldPos;
out vec3  Normal;
out vec3  ViewNormal;
out vec3  Albedo;
out vec4  LightSpacePos;
out float ViewDepth;
out float Wear;
out vec4  Wet;              // grass blades: the wet ground they stand in

const float SHADOW_NORMAL_OFFSET = 0.06; // avoids self-shadowing acne
const float DECAL_BIAS       = 0.02;  // decals are drawn this much towards the eye ...
const float DECAL_BIAS_SLOPE = 0.004; // ... plus this per meter away, so the wobbling
                                      // ground never pokes through them

void main() {
    vec3 world = vec3(model * vec4(aPos, 1.0));

    // Trampled grass sinks a little
    Wear = 0.0;
    if (terrainSize > 0.0) {
        Wear = texture(wearMap, world.xz / terrainSize + 0.5).r;
        world.y -= Wear * grassDepth;
    } else if (decalSize > 0.0) {
        world.y -= texture(wearMap, world.xz / decalSize + 0.5).r * grassDepth;
    }
    vec3 normal = aNormal;
    Wet = vec4(0.0);
    if (grass > 0.0) {
        // Blades stand on the ground and sink with it; trampled ones (and in mud) lie flat; tips sway
        float h = aNormal.y;
        Wear = texture(wearMap, world.xz / grass + 0.5).r;
        Wet  = texture(waterMap, world.xz / grass + 0.5);
        world.y -= Wear * grassDepth + h * smoothstep(0.08, 0.5, max(Wear, Wet.a)) * 0.9;
        world.xz += h * vec2(sin(boilTime * 1.7 + world.x * 0.35 + world.z * 0.2),
                             cos(boilTime * 1.3 + world.z * 0.35)) * 0.1;
        normal = vec3(0.0, 1.0, 0.0);
    }

    world += wobble(world, boilTime);

    Normal        = normalize(mat3(model) * normal);
    ViewNormal    = mat3(view) * Normal;
    WorldPos      = world;
    Albedo        = aColor;
    LightSpacePos = lightSpaceMatrix * vec4(world + Normal * SHADOW_NORMAL_OFFSET, 1.0);

    vec4 viewPos = view * vec4(world, 1.0);
    ViewDepth    = -viewPos.z;
    if (decalSize > 0.0) { // along the view ray: same spot on screen, just in front
        float d = max(length(viewPos.xyz), 1e-3);
        viewPos.xyz *= max(1.0 - (DECAL_BIAS + DECAL_BIAS_SLOPE * d) / d, 0.05);
    }
    gl_Position  = projection * viewPos;
}