Entropie git · main
Entropie festival game; first steps
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.gzentropie/assets/shaders/scene.vert 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;
}