Skip to main content

scenix_material/
lambert.rs

1use alloc::string::String;
2
3use scenix_core::{Color, TextureId};
4use scenix_math::Vec3;
5
6use crate::traits::{double_sided_bit, option_texture_bit};
7use crate::{AlphaMode, FEATURE_ALBEDO_TEXTURE, Material, PipelineKey, ShaderKind};
8
9/// Diffuse-only material for fast lit surfaces.
10#[derive(Clone, Debug, PartialEq)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct LambertMaterial {
13    /// Human-readable material name.
14    pub name: String,
15    /// Diffuse color in linear RGBA.
16    pub color: Color,
17    /// Optional diffuse color texture.
18    pub color_texture: Option<TextureId>,
19    /// Emissive RGB color in linear space.
20    pub emissive: Vec3,
21    /// Alpha behavior.
22    pub alpha_mode: AlphaMode,
23    /// Whether the material is rendered double-sided.
24    pub double_sided: bool,
25}
26
27impl LambertMaterial {
28    /// Creates a default opaque white Lambert material.
29    #[inline]
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    /// Returns this material with a diffuse color.
35    #[inline]
36    pub const fn color(mut self, color: Color) -> Self {
37        self.color = color;
38        self
39    }
40}
41
42impl Default for LambertMaterial {
43    #[inline]
44    fn default() -> Self {
45        Self {
46            name: String::new(),
47            color: Color::WHITE,
48            color_texture: None,
49            emissive: Vec3::ZERO,
50            alpha_mode: AlphaMode::Opaque,
51            double_sided: false,
52        }
53    }
54}
55
56impl Material for LambertMaterial {
57    #[inline]
58    fn pipeline_key(&self) -> PipelineKey {
59        PipelineKey::new(
60            ShaderKind::Lambert,
61            self.alpha_mode.pipeline_alpha(),
62            double_sided_bit(self.double_sided)
63                | option_texture_bit(&self.color_texture, FEATURE_ALBEDO_TEXTURE),
64        )
65    }
66
67    #[inline]
68    fn is_transparent(&self) -> bool {
69        self.alpha_mode.is_transparent()
70    }
71
72    #[inline]
73    fn double_sided(&self) -> bool {
74        self.double_sided
75    }
76
77    #[inline]
78    fn alpha_cutoff(&self) -> Option<f32> {
79        self.alpha_mode.cutoff()
80    }
81}