From 5ce6133e120bd5e3d7490db1872bc8b667a0fb4f Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 19 May 2024 18:21:53 +0200 Subject: fix(engine): use ambient light from GlobalLight --- engine/src/lighting.rs | 4 +--- engine/src/material.rs | 22 ++++++++++++++++++++++ engine/src/renderer/mod.rs | 39 ++++++++++++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 12 deletions(-) (limited to 'engine') diff --git a/engine/src/lighting.rs b/engine/src/lighting.rs index d08276e..f41437a 100644 --- a/engine/src/lighting.rs +++ b/engine/src/lighting.rs @@ -6,7 +6,6 @@ use crate::util::builder; #[derive(Debug, Clone, Component)] pub struct LightSource { - pub ambient: Color, pub diffuse: Color, pub specular: Color, } @@ -16,7 +15,6 @@ impl Default for LightSource fn default() -> Self { Self { - ambient: Color { red: 0.2, green: 0.2, blue: 0.2 }, diffuse: Color { red: 0.5, green: 0.5, blue: 0.5 }, specular: Color { red: 1.0, green: 1.0, blue: 1.0 }, } @@ -30,7 +28,7 @@ builder! { #[non_exhaustive] pub struct GlobalLight { - pub ambient_offset: Color, + pub ambient: Color, } } diff --git a/engine/src/material.rs b/engine/src/material.rs index 5e360cd..5c59a9a 100644 --- a/engine/src/material.rs +++ b/engine/src/material.rs @@ -3,6 +3,7 @@ use ecs::Component; use crate::color::Color; use crate::data_types::dimens::Dimens; use crate::texture::{Id as TextureId, Texture}; +use crate::util::builder; #[derive(Debug, Clone, Component)] #[non_exhaustive] @@ -176,6 +177,27 @@ impl Default for Builder } } +builder! { +/// Material flags. +#[builder(name = FlagsBuilder, derives = (Debug, Default, Clone))] +#[derive(Debug, Default, Clone, Component)] +#[non_exhaustive] +pub struct Flags +{ + /// Whether to use material's ambient color instead of the global ambient color. + /// Default is `false` + pub use_ambient_color: bool, +} +} + +impl Flags +{ + pub fn builder() -> FlagsBuilder + { + FlagsBuilder::default() + } +} + fn create_1x1_white_texture() -> Texture { Texture::new_from_color(&Dimens { width: 1, height: 1 }, &Color::WHITE_U8) diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 2035a3c..4f9d7e6 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -13,7 +13,7 @@ use crate::color::Color; use crate::data_types::dimens::Dimens; use crate::event::{Present as PresentEvent, Start as StartEvent}; use crate::lighting::{GlobalLight, LightSource}; -use crate::material::Material; +use crate::material::{Flags as MaterialFlags, Material}; use crate::matrix::Matrix; use crate::mesh::Mesh; use crate::opengl::buffer::{Buffer, Usage as BufferUsage}; @@ -91,7 +91,13 @@ fn initialize(window: Single) } fn render( - query: Query<(Mesh, ShaderProgram, Material, Transform)>, + query: Query<( + Mesh, + ShaderProgram, + Material, + Option, + Transform, + )>, light_source_query: Query<(LightSource, Transform)>, camera_query: Query<(Camera,)>, window: Single, @@ -125,7 +131,11 @@ fn render( clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); - for (mesh, shader_program, material, transform) in &query { + for (mesh, shader_program, material, material_flags, transform) in &query { + let material_flags = material_flags + .map(|material_flags| material_flags.clone()) + .unwrap_or_default(); + let shader_program = gl_shader_programs .entry(shader_program.u64_hash()) .or_insert_with(|| create_gl_shader_program(&shader_program).unwrap()); @@ -139,6 +149,7 @@ fn render( apply_light( &material, + &material_flags, &global_light, shader_program, light_source @@ -346,6 +357,7 @@ fn apply_transformation_matrices( fn apply_light( material: &Material, + material_flags: &MaterialFlags, global_light: &GlobalLight, gl_shader_program: &mut GlShaderProgram, light_source: Option<(&LightSource, &Transform)>, @@ -361,11 +373,12 @@ fn apply_light( gl_shader_program.set_uniform_vec_3fv( cstr!("light.ambient"), - &light_source - .map_or(Color::WHITE_F32, |(light_source, _)| { - light_source.ambient.clone() - }) - .into(), + // There cannot be both a material ambient color and a global ambient color + &if material_flags.use_ambient_color { + Color::WHITE_F32.into() + } else { + global_light.ambient.clone().into() + }, ); gl_shader_program.set_uniform_vec_3fv( @@ -388,7 +401,15 @@ fn apply_light( gl_shader_program.set_uniform_vec_3fv( cstr!("material.ambient"), - &(material.ambient.clone() + global_light.ambient_offset.clone()).into(), + // When using the material ambient color is disabled, the ambient color has to be + // white and not black since the material's ambient color is multiplied + // with the global ambient light in the shader + &if material_flags.use_ambient_color { + material.ambient.clone() + } else { + Color::WHITE_F32 + } + .into(), ); gl_shader_program -- cgit v1.2.3-18-g5258