Files
Test_Game/shaders/fog.fs
2025-08-31 22:08:18 -05:00

74 lines
2.4 KiB
GLSL

#version 330 core
in vec2 vTexCoord;
in vec3 vWorldPos;
uniform sampler2D texture0;
// --- Soft bubble (kept) ---
uniform vec3 u_playerPos;
uniform float u_inner;
uniform float u_outer;
uniform float u_minShadow;
// --- Flashlight cone + distance ---
uniform vec3 u_spotDir; // normalized camera forward
uniform float u_spotCos; // cos(half-angle)
uniform float u_spotSoft; // base penumbra width in cos-space
uniform float u_lightRange; // bright zone distance (>0)
uniform float u_lightFade; // fade width beyond range
// --- NEW: decouple brightness + widen with distance ---
uniform float u_intensity; // flashlight peak brightness (independent of range)
uniform float u_beamSpread; // additional penumbra growth per unit distance (0..~0.5)
// Alpha cut (trees, grass)
uniform float u_alphaCutoff;
out vec4 finalColor;
// Helpers
float remap01(float x, float a, float b) {
return clamp((x - a) / max(b - a, 1e-5), 0.0, 1.0);
}
float invsq(float d, float r) {
float s = d / max(r, 1e-4);
return 1.0 / (1.0 + s*s);
}
void main() {
vec4 texel = texture(texture0, vTexCoord);
if (texel.a < u_alphaCutoff) discard;
float dist = length(vWorldPos - u_playerPos);
// (A) Soft ambient bubble around the player (unchanged)
float bubble = 1.0 - remap01(dist, u_inner, u_outer); // 1 near, 0 far
float ambient = mix(1.0 - clamp(u_minShadow,0.0,1.0), 0.0, 1.0 - bubble);
// (B) Flashlight cone with penumbra + distance drop + widening
vec3 L = normalize(vWorldPos - u_playerPos);
float cosTheta = dot(normalize(u_spotDir), L);
// Widen penumbra with distance so long ranges don't look like a laser
float distNorm = dist / max(u_lightRange, 1e-4);
float softWide = clamp(u_spotSoft + u_beamSpread * distNorm, 0.0, 0.8);
float innerEdge = u_spotCos;
float outerEdge = clamp(u_spotCos - softWide, -1.0, 1.0);
float spotA = smoothstep(outerEdge, innerEdge, cosTheta);
spotA *= spotA; // mild hotspot
// Distance attenuation: inverse-square * soft fade band
float band = 1.0 - remap01(dist, u_lightRange, u_lightRange + u_lightFade);
float lightD = invsq(dist, u_lightRange) * band;
// Decoupled brightness
float flashlight = u_intensity * spotA * lightD;
// Compose
float light = clamp(ambient + flashlight, 0.0, 1.0);
finalColor = vec4(texel.rgb * light, texel.a);
}