Skip to main content

scenix_material/
points.rs

1use scenix_core::Color;
2
3use crate::{
4    AlphaMode, FEATURE_SIZE_ATTENUATION, Material, PipelineAlphaMode, PipelineKey, ShaderKind,
5};
6
7/// Point material for point-list geometry.
8#[derive(Clone, Copy, Debug, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct PointsMaterial {
11    /// Point color in linear RGBA.
12    pub color: Color,
13    /// Point size in logical pixels.
14    pub size: f32,
15    /// Whether point size attenuates with depth.
16    pub size_attenuation: bool,
17    /// Alpha behavior.
18    pub alpha_mode: AlphaMode,
19}
20
21impl PointsMaterial {
22    /// Creates a default white point material.
23    #[inline]
24    pub const fn new() -> Self {
25        Self {
26            color: Color::WHITE,
27            size: 1.0,
28            size_attenuation: true,
29            alpha_mode: AlphaMode::Opaque,
30        }
31    }
32}
33
34impl Default for PointsMaterial {
35    #[inline]
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl Material for PointsMaterial {
42    #[inline]
43    fn pipeline_key(&self) -> PipelineKey {
44        let bits = if self.size_attenuation {
45            FEATURE_SIZE_ATTENUATION
46        } else {
47            0
48        };
49        let alpha = if self.color.a < 1.0 {
50            PipelineAlphaMode::Blend
51        } else {
52            self.alpha_mode.pipeline_alpha()
53        };
54        PipelineKey::new(ShaderKind::Points, alpha, bits)
55    }
56
57    #[inline]
58    fn is_transparent(&self) -> bool {
59        self.alpha_mode.is_transparent() || self.color.a < 1.0
60    }
61
62    #[inline]
63    fn double_sided(&self) -> bool {
64        true
65    }
66
67    #[inline]
68    fn alpha_cutoff(&self) -> Option<f32> {
69        self.alpha_mode.cutoff()
70    }
71}