Basic flashlight
This commit is contained in:
47
main.c
47
main.c
@@ -200,8 +200,8 @@ int main(void)
|
||||
|
||||
// Load skybox shader
|
||||
Shader skyboxShader = LoadShader(
|
||||
"resources/shaders/skybox.vs",
|
||||
"resources/shaders/skybox.fs"
|
||||
"shaders/skybox.vs",
|
||||
"shaders/skybox.fs"
|
||||
);
|
||||
|
||||
// Attach shader to skybox
|
||||
@@ -221,7 +221,7 @@ int main(void)
|
||||
SetShaderValue(skyboxShader, GetShaderLocation(skyboxShader, "doGamma"), &doGamma, SHADER_UNIFORM_INT);
|
||||
|
||||
// Load the fog-of-war shader
|
||||
Shader fog = LoadShader("resources/shaders/fog.vs", "resources/shaders/fog.fs");
|
||||
Shader fog = LoadShader("shaders/fog.vs", "shaders/fog.fs");
|
||||
|
||||
// Grab uniform locations (cache them)
|
||||
int locPlayer = GetShaderLocation(fog, "u_playerPos");
|
||||
@@ -236,6 +236,16 @@ int main(void)
|
||||
// Optional if you added the sharpness curve in the shader
|
||||
int locSharpness = GetShaderLocation(fog, "u_sharpness");
|
||||
|
||||
//Flashlight
|
||||
int locSpotDir = GetShaderLocation(fog, "u_spotDir");
|
||||
int locSpotCos = GetShaderLocation(fog, "u_spotCos");
|
||||
int locSpotSoft = GetShaderLocation(fog, "u_spotSoft");
|
||||
int locLightRange = GetShaderLocation(fog, "u_lightRange");
|
||||
int locLightFade = GetShaderLocation(fog, "u_lightFade");
|
||||
int locIntensity = GetShaderLocation(fog, "u_intensity");
|
||||
int locBeamSpread = GetShaderLocation(fog, "u_beamSpread");
|
||||
|
||||
|
||||
// Let raylib know which matrices the shader expects
|
||||
fog.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(fog, "matModel");
|
||||
fog.locs[SHADER_LOC_MATRIX_VIEW] = GetShaderLocation(fog, "matView");
|
||||
@@ -250,17 +260,33 @@ int main(void)
|
||||
|
||||
// Fog/vignette tuning
|
||||
float inner = 0.0f; // start radius (center under player)
|
||||
float outer = 45.0f; // how far until full fog
|
||||
float minShadow = 0.45f; // baseline darkness at the center (0 = none, 1 = pitch black)
|
||||
float outer = 20.0f; // how far until full fog
|
||||
float minShadow = 0.9f; // baseline darkness at the center (0 = none, 1 = pitch black)
|
||||
float sharpness = 2.0f; // steeper edge (optional if shader uses it)
|
||||
Vector4 fogColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
|
||||
// Flashligh tuning
|
||||
float spotAngleDeg = 35.0f; //cone angle
|
||||
float spotCos = cosf(DEG2RAD * (spotAngleDeg * 0.5f));
|
||||
float spotSoft = 0.05f;
|
||||
float lightRange = 150.0f;
|
||||
float lightFade = 10.0f;
|
||||
float intensity = 0.25f; // try 0.7–1.5 to taste
|
||||
float beamSpread = 0.00f; // try 0.15–0.35; higher = less “laser” at distance
|
||||
|
||||
SetShaderValue(fog, locIntensity, &intensity, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locBeamSpread, &beamSpread, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locSpotCos, &spotCos, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locSpotSoft, &spotSoft, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locLightRange, &lightRange, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locLightFade, &lightFade, SHADER_UNIFORM_FLOAT);
|
||||
|
||||
SetShaderValue(fog, locInner, &inner, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locOuter, &outer, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locMinShadow, &minShadow, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(fog, locFogColor, &fogColor, SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(fog, locSharpness, &sharpness, SHADER_UNIFORM_FLOAT);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
@@ -367,8 +393,15 @@ int main(void)
|
||||
case STATE_GAME:
|
||||
{
|
||||
ClearBackground(BLACK);
|
||||
|
||||
Vector3 camPos = g.player.camera.position;
|
||||
Vector3 camFwd = Vector3Normalize(Vector3Subtract(g.player.camera.target, camPos));
|
||||
|
||||
SetShaderValue(fog, locPlayer, &g.player.position, SHADER_UNIFORM_VEC3);
|
||||
// Camera forward (normalize target - position)
|
||||
Vector3 forward = Vector3Normalize(Vector3Subtract(g.player.camera.target, g.player.camera.position));
|
||||
|
||||
SetShaderValue(fog, locPlayer, &camPos, SHADER_UNIFORM_VEC3);
|
||||
SetShaderValue(fog, locSpotDir, &camFwd, SHADER_UNIFORM_VEC3);
|
||||
|
||||
BeginMode3D(g.player.camera);
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#version 330
|
||||
|
||||
in vec3 vWorldPos;
|
||||
in vec2 vTexCoord;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec3 u_playerPos; // player world pos
|
||||
uniform float u_inner; // start of vignette (m)
|
||||
uniform float u_outer; // end of vignette (m) u_outer > u_inner
|
||||
uniform float u_minShadow; // baseline darkness at center [0..1], e.g. 0.15
|
||||
uniform vec4 u_fogColor; // usually vec4(0,0,0,1)
|
||||
uniform float u_alphaCutoff; // for trees/billboards too
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel = texture(texture0, vTexCoord);
|
||||
if (texel.a < u_alphaCutoff) discard;
|
||||
|
||||
// distance on the ground plane
|
||||
float distXZ = length(vWorldPos.xz - u_playerPos.xz);
|
||||
|
||||
// 0 at u_inner, 1 at u_outer
|
||||
float t = smoothstep(u_inner, u_outer, distXZ);
|
||||
|
||||
// add baseline shadow so center is not fully bright
|
||||
t = u_minShadow + (1.0 - u_minShadow) * t;
|
||||
|
||||
vec3 rgb = mix(texel.rgb, u_fogColor.rgb, t);
|
||||
finalColor = vec4(rgb, texel.a);
|
||||
}
|
||||
73
shaders/fog.fs
Normal file
73
shaders/fog.fs
Normal file
@@ -0,0 +1,73 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user