summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-05-22 20:39:26 +0200
committerHampusM <hampus@hampusmat.com>2024-05-22 20:39:26 +0200
commitd4b61dd34b06119e87c8932ab7718d432dbc6a4f (patch)
tree2240158176c11eac545a1b50bbe644700b67ab51
parent8398025d7927564637e1ea67234665571dc7bcc5 (diff)
feat(engine): add point light attenuation
-rw-r--r--engine/fragment.glsl5
-rw-r--r--engine/light.glsl16
-rw-r--r--engine/src/lighting.rs23
-rw-r--r--engine/src/renderer/mod.rs21
4 files changed, 63 insertions, 2 deletions
diff --git a/engine/fragment.glsl b/engine/fragment.glsl
index 428e87f..a9d192b 100644
--- a/engine/fragment.glsl
+++ b/engine/fragment.glsl
@@ -30,5 +30,10 @@ void main()
in_texture_coords
);
+ float attenuation = calc_attenuation(light, in_frag_pos);
+
+ diffuse_light *= attenuation;
+ specular_light *= attenuation;
+
FragColor = vec4((ambient_light + diffuse_light + specular_light), 1.0);
}
diff --git a/engine/light.glsl b/engine/light.glsl
index 49026ec..04a42f5 100644
--- a/engine/light.glsl
+++ b/engine/light.glsl
@@ -13,14 +13,17 @@ struct Material {
float shininess;
};
-struct Light {
+struct PointLight {
vec3 position;
vec3 diffuse;
vec3 specular;
+ float constant;
+ float linear;
+ float quadratic;
};
uniform Material material;
-uniform Light light;
+uniform PointLight light;
vec3 calc_ambient_light(in vec2 texture_coords)
{
@@ -56,4 +59,13 @@ vec3 calc_specular_light(
);
}
+float calc_attenuation(in PointLight point_light, in vec3 position)
+{
+ float light_distance = length(point_light.position - position);
+
+ return 1.0 / (point_light.constant + point_light.linear
+ * light_distance + point_light.quadratic
+ * pow(light_distance, 2));
+}
+
#endif
diff --git a/engine/src/lighting.rs b/engine/src/lighting.rs
index bfc2d9b..ffa2645 100644
--- a/engine/src/lighting.rs
+++ b/engine/src/lighting.rs
@@ -11,6 +11,7 @@ pub struct PointLight
{
pub diffuse: Color<f32>,
pub specular: Color<f32>,
+ pub attenuation_params: AttenuationParams,
}
}
@@ -29,6 +30,7 @@ impl Default for PointLight
Self {
diffuse: Color { red: 0.5, green: 0.5, blue: 0.5 },
specular: Color { red: 1.0, green: 1.0, blue: 1.0 },
+ attenuation_params: AttenuationParams::default(),
}
}
}
@@ -41,6 +43,27 @@ impl Default for PointLightBuilder
}
}
+/// Parameters for light [attenuation](https://en.wikipedia.org/wiki/Attenuation).
+#[derive(Debug, Clone)]
+pub struct AttenuationParams
+{
+ pub constant: f32,
+ pub linear: f32,
+ pub quadratic: f32,
+}
+
+impl Default for AttenuationParams
+{
+ fn default() -> Self
+ {
+ Self {
+ constant: 1.0,
+ linear: 0.0,
+ quadratic: 0.0,
+ }
+ }
+}
+
builder! {
/// Global light properties.
#[builder(name = GlobalLightBuilder, derives = (Debug, Clone, Default))]
diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs
index e736165..ad587b5 100644
--- a/engine/src/renderer/mod.rs
+++ b/engine/src/renderer/mod.rs
@@ -389,6 +389,27 @@ fn apply_light(
.into(),
);
+ gl_shader_program.set_uniform_1fv(
+ cstr!("light.constant"),
+ point_light.map_or(1.0, |(light_source, _)| {
+ light_source.attenuation_params.constant
+ }),
+ );
+
+ gl_shader_program.set_uniform_1fv(
+ cstr!("light.linear"),
+ point_light.map_or(0.0, |(light_source, _)| {
+ light_source.attenuation_params.linear
+ }),
+ );
+
+ gl_shader_program.set_uniform_1fv(
+ cstr!("light.quadratic"),
+ point_light.map_or(0.0, |(light_source, _)| {
+ light_source.attenuation_params.quadratic
+ }),
+ );
+
gl_shader_program.set_uniform_vec_3fv(
cstr!("material.ambient"),
&if material_flags.use_ambient_color {