#[cfg(feature = "wgpu")]
#[derive(Clone, Default)]
pub struct RenderLighting {
pub lights_data: Vec<crate::wgpu::passes::geometry::projection::LightData>,
pub num_directional_lights: u32,
pub directional_light_direction: [f32; 4],
pub has_directional_light: bool,
pub entity_to_lights_index: std::collections::HashMap<nightshade_ecs::Entity, usize>,
pub cascade_view_projections: [[[f32; 4]; 4]; crate::wgpu::passes::NUM_SHADOW_CASCADES],
pub cascade_diameters: [f32; crate::wgpu::passes::NUM_SHADOW_CASCADES],
pub cascade_split_distances: [f32; crate::wgpu::passes::NUM_SHADOW_CASCADES],
pub light_view_projection: [[f32; 4]; 4],
pub shadow_bias: f32,
pub shadow_normal_bias: f32,
pub directional_light_size: f32,
pub shadows_enabled: f32,
pub area_lights_data: Vec<crate::wgpu::passes::geometry::projection::AreaLightData>,
pub area_entity_to_index: std::collections::HashMap<nightshade_ecs::Entity, usize>,
pub sun_direction: nalgebra_glm::Vec3,
pub sun_color: nalgebra_glm::Vec3,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum RenderLightType {
#[default]
Directional,
Point,
Spot,
Area,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum RenderAreaLightShape {
#[default]
Rectangle,
Disk,
Sphere,
Tube,
}
#[derive(Clone, Default)]
pub struct RenderLightData {
pub light_type: RenderLightType,
pub color: nalgebra_glm::Vec3,
pub intensity: f32,
pub range: f32,
pub inner_cone_angle: f32,
pub outer_cone_angle: f32,
pub cast_shadows: bool,
pub shadow_bias: f32,
pub shadow_resolution: u32,
pub shadow_distance: f32,
pub cookie_texture: Option<String>,
pub area_shape: RenderAreaLightShape,
pub area_width: f32,
pub area_height: f32,
pub area_radius: f32,
pub area_two_sided: bool,
pub area_emissive_texture: Option<String>,
pub shadow_normal_bias: f32,
pub shadow_softness: f32,
}
#[derive(Clone)]
pub struct RenderLight {
pub entity: nightshade_ecs::Entity,
pub light: RenderLightData,
pub transform: nalgebra_glm::Mat4,
}
fn base_light_data(
light_type: RenderLightType,
color: nalgebra_glm::Vec3,
intensity: f32,
range: f32,
) -> RenderLightData {
RenderLightData {
light_type,
color,
intensity,
range,
inner_cone_angle: 0.0,
outer_cone_angle: std::f32::consts::FRAC_PI_4,
cast_shadows: false,
shadow_bias: 0.0015,
shadow_resolution: 2048,
shadow_distance: 100.0,
cookie_texture: None,
area_shape: RenderAreaLightShape::Rectangle,
area_width: 1.0,
area_height: 1.0,
area_radius: 0.5,
area_two_sided: false,
area_emissive_texture: None,
shadow_normal_bias: 0.02,
shadow_softness: 1.0,
}
}
fn direction_transform(
position: nalgebra_glm::Vec3,
direction: nalgebra_glm::Vec3,
) -> nalgebra_glm::Mat4 {
let forward = direction.normalize();
let world_up = if forward.y.abs() > 0.99 {
nalgebra_glm::vec3(0.0, 0.0, 1.0)
} else {
nalgebra_glm::vec3(0.0, 1.0, 0.0)
};
let right = forward.cross(&world_up).normalize();
let up = right.cross(&forward);
nalgebra_glm::Mat4::new(
right.x, up.x, -forward.x, position.x, right.y, up.y, -forward.y, position.y, right.z,
up.z, -forward.z, position.z, 0.0, 0.0, 0.0, 1.0,
)
}
impl RenderLight {
pub fn directional(
entity: nightshade_ecs::Entity,
direction: nalgebra_glm::Vec3,
color: nalgebra_glm::Vec3,
intensity: f32,
) -> Self {
let mut light = base_light_data(RenderLightType::Directional, color, intensity, 0.0);
light.cast_shadows = true;
Self {
entity,
light,
transform: direction_transform(nalgebra_glm::Vec3::zeros(), direction),
}
}
pub fn point(
entity: nightshade_ecs::Entity,
position: nalgebra_glm::Vec3,
color: nalgebra_glm::Vec3,
intensity: f32,
range: f32,
) -> Self {
Self {
entity,
light: base_light_data(RenderLightType::Point, color, intensity, range),
transform: nalgebra_glm::translation(&position),
}
}
pub fn spot(
entity: nightshade_ecs::Entity,
position: nalgebra_glm::Vec3,
direction: nalgebra_glm::Vec3,
color: nalgebra_glm::Vec3,
intensity: f32,
range: f32,
cone: [f32; 2],
) -> Self {
let mut light = base_light_data(RenderLightType::Spot, color, intensity, range);
light.inner_cone_angle = cone[0];
light.outer_cone_angle = cone[1];
Self {
entity,
light,
transform: direction_transform(position, direction),
}
}
}
#[derive(Clone, Default)]
pub struct RenderShadowCasters {
pub skinned: Vec<nightshade_ecs::Entity>,
}