Skip to main content

nightshade_api/
environment.rs

1//! Background, grid, fog, bloom, time of day, and other scene wide settings.
2
3use crate::runner::{SUN_NAME, lookup_named};
4use nightshade::ecs::graphics::resources::DepthOfField;
5use nightshade::prelude::*;
6
7/// What fills the space behind your scene.
8pub enum Background {
9    /// The procedural sky gradient. The default.
10    Sky,
11    /// The sky with volumetric clouds.
12    CloudySky,
13    /// A procedural starfield.
14    Space,
15    /// A procedural nebula with stars.
16    Nebula,
17    /// A procedural sunset gradient.
18    Sunset,
19    /// A solid color, linear RGBA.
20    Color([f32; 4]),
21    /// An equirectangular hdr image used as a skybox.
22    Hdr(Vec<u8>),
23}
24
25/// Sets the background. [`Background::Color`] switches the atmosphere off and
26/// sets the clear color together, which is the pairing the engine needs. The
27/// procedural skies also recapture image based lighting so reflective
28/// surfaces pick up the new sky.
29pub fn set_background(world: &mut World, background: Background) {
30    match background {
31        Background::Sky => set_atmosphere(world, Atmosphere::Sky),
32        Background::CloudySky => set_atmosphere(world, Atmosphere::CloudySky),
33        Background::Space => set_atmosphere(world, Atmosphere::Space),
34        Background::Nebula => set_atmosphere(world, Atmosphere::Nebula),
35        Background::Sunset => set_atmosphere(world, Atmosphere::Sunset),
36        Background::Color(color) => {
37            world.resources.render_settings.atmosphere = Atmosphere::None;
38            world.resources.render_settings.clear_color = color;
39        }
40        Background::Hdr(bytes) => {
41            load_hdr_skybox(world, bytes);
42        }
43    }
44}
45
46fn set_atmosphere(world: &mut World, atmosphere: Atmosphere) {
47    world.resources.render_settings.atmosphere = atmosphere;
48    capture_procedural_atmosphere_ibl(world, atmosphere, 0.0);
49}
50
51/// Shows or hides the reference grid. On by default.
52#[inline]
53pub fn show_grid(world: &mut World, enabled: bool) {
54    world.resources.debug_draw.show_grid = enabled;
55}
56
57/// Sets the ambient light color, linear RGBA.
58#[inline]
59pub fn set_ambient(world: &mut World, color: [f32; 4]) {
60    world.resources.render_settings.ambient_light = color;
61}
62
63/// Enables distance fog between `Fog::start` and `Fog::end`, or disables it
64/// with `None`.
65#[inline]
66pub fn set_fog(world: &mut World, fog: Option<Fog>) {
67    world.resources.render_settings.fog = fog;
68}
69
70/// Toggles bloom. Emissive materials glow when this is on.
71#[inline]
72pub fn set_bloom(world: &mut World, enabled: bool) {
73    world.resources.render_settings.bloom_enabled = enabled;
74}
75
76/// Sets the hour of the day from 0.0 to 24.0. Switches the sky to the day
77/// and night atmosphere and puts the default sun under its control, so the
78/// sun arcs and the light warms and cools with the hour. The hour you pass is
79/// authoritative, so call this every frame to animate time.
80pub fn set_time_of_day(world: &mut World, hour: f32) {
81    if world
82        .resources
83        .renderer_state
84        .day_night
85        .sun_entity
86        .is_none()
87    {
88        world.resources.renderer_state.day_night.sun_entity = lookup_named(world, SUN_NAME);
89    }
90    world.resources.render_settings.atmosphere = Atmosphere::DayNight;
91    world.resources.renderer_state.day_night.auto_cycle = true;
92    world.resources.renderer_state.day_night.speed = 0.0;
93    world.resources.renderer_state.day_night.hour = hour;
94}
95
96/// Sets the manual exposure multiplier. 1.0 is neutral, above brightens,
97/// below darkens.
98#[inline]
99pub fn set_exposure(world: &mut World, exposure: f32) {
100    world.resources.render_settings.color_grading.exposure = exposure;
101}
102
103/// Sets depth of field. The engine ships presets: `DepthOfField::portrait()`,
104/// `cinematic()`, `macro_shot()`, `landscape()`, and `tilt_shift()`. Disable
105/// it by passing a default with `enabled` false.
106#[inline]
107pub fn set_depth_of_field(world: &mut World, depth_of_field: DepthOfField) {
108    world.resources.render_settings.depth_of_field = depth_of_field;
109}
110
111/// Sets the window title.
112#[inline]
113pub fn set_title(world: &mut World, title: &str) {
114    world.resources.window.title = title.to_string();
115}
116
117/// Saves a screenshot of the next rendered frame to `path` as a png.
118pub fn screenshot(world: &mut World, path: std::path::PathBuf) {
119    queue_render_command(
120        world,
121        RenderCommand::CaptureScreenshot {
122            path: Some(path),
123            max_dimension: None,
124        },
125    );
126}