diff --git a/shaders/lighting.glsl b/shaders/lighting.glsl index 22ad009..cd07e60 100644 --- a/shaders/lighting.glsl +++ b/shaders/lighting.glsl @@ -1,16 +1,44 @@ uniform sampler2D texture; -uniform float ambient; +uniform vec2 resolution; +uniform vec2 mouse; +uniform float time; uniform bool has_texture; -void main() -{ - // lookup the pixel in the texture - vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); +// The RGB values are the ambient light color +// and the alpha is the ambient intensity +uniform vec4 ambientData; +// The RGB values are the light color +// and the alpha is the light intensity +uniform vec4 lightData; +// Maximum radius of the light +uniform float lightSize; - // multiply it by the color - vec4 col = gl_Color; - if (has_texture) { - col = gl_Color * pixel; - } - gl_FragColor = vec4(col.x * ambient, col.y * ambient, col.z * ambient, col.w); +void main() { + // Light's position + vec2 position = mouse/resolution.xx; + + // Makes the light change its size slightly to make a fire effect + float maxDistance = lightSize + 0.015*sin(time); + // Gets the distance from the light's position and the fragment coord + float distance = distance(gl_FragCoord.xy/resolution.xx, position); + // Calculates the amount of light for the fragment + float value = 1.0 - smoothstep(-0.2, maxDistance, distance); + + // Gets the original color from the texture + vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); + if (!has_texture) { + pixel = gl_Color; + } + + // Applies the ambient light to the original pixel color + vec3 ambient = pixel.rgb * ambientData.rgb * ambientData.a; + + // Calculates the light color for the pixel + vec3 light = lightData.rgb * lightData.a * clamp(value, 0.0, 1.0); + + // Applies the light to the pixel + vec3 intensity = ambient + light; + vec3 final = pixel.rgb * intensity; + + gl_FragColor = vec4(final, 1.0); } \ No newline at end of file diff --git a/src/game.rs b/src/game.rs index 5d8f434..092f534 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,8 +1,13 @@ mod player; -use sfml::graphics::{ - Color, Rect, RectangleShape, RenderStates, RenderTarget, RenderWindow, Shape, Sprite, - Transformable, +use sfml::{ + graphics::{ + glsl::{Vec2, Vec4}, + Color, Rect, RectangleShape, RenderStates, RenderTarget, RenderWindow, Shape, Sprite, + Transformable, + }, + system::Clock, + SfBox, }; use crate::{ @@ -25,6 +30,7 @@ pub struct GameState { pub prev_biome: Biome, pub worldgen: Worldgen, pub ambient_light: f32, + pub clock: SfBox, } #[derive(PartialEq, Eq, Clone, Copy)] @@ -77,8 +83,39 @@ impl GameState { rw.draw(&rect_sh); } pub fn render_pre_step(&mut self, res: &mut Res) { + res.lighting_shader.set_uniform_current_texture("texture"); res.lighting_shader - .set_uniform_float("ambient", self.ambient_light); + .set_uniform_float("time", self.clock.elapsed_time().as_seconds() * 10.0); + res.lighting_shader.set_uniform_vec2( + "mouse", + Vec2::new( + NATIVE_RESOLUTION.w as f32 / 2.0, + NATIVE_RESOLUTION.h as f32 / 2.0, + ), + ); + res.lighting_shader.set_uniform_vec2( + "resolution", + Vec2::new(NATIVE_RESOLUTION.w as f32, NATIVE_RESOLUTION.h as f32), + ); + res.lighting_shader.set_uniform_vec4( + "lightData", + Vec4 { + x: 1.0, + y: 0.8, + z: 0.2, + w: 2.0, + }, + ); + res.lighting_shader.set_uniform_vec4( + "ambientData", + Vec4 { + x: 0.3, + y: 0.3, + z: 0.8, + w: 0.3, + }, + ); + res.lighting_shader.set_uniform_float("lightSize", 0.3); } } @@ -113,6 +150,7 @@ impl Default for GameState { prev_biome: Biome::Surface, worldgen: Worldgen::default(), ambient_light: 1.0, + clock: Clock::start(), } } }