nightshade-api 0.53.0

Procedural high level API for the nightshade game engine
Documentation
//! Post-processing and render controls: toggle bloom, SSAO, SSR, SSGI, TAA, and
//! fog; cycle tonemap and shading mode; drive depth of field, exposure, color
//! grading, shadows, render layers, and screenshots.

use nightshade_api::nightshade::render::config::DepthOfFieldQuality;
use nightshade_api::prelude::*;

struct State {
    bloom: bool,
    ssao: bool,
    ssr: bool,
    ssgi: bool,
    taa: bool,
    fog: bool,
    tonemap: usize,
    shading: usize,
    light: Entity,
    label: Entity,
}

fn main() {
    run(
        |world| {
            set_background(world, Background::Color([0.01, 0.01, 0.02, 1.0]));
            show_grid(world, false);
            spawn_floor(world, 16.0);

            let glow = spawn_sphere(world, vec3(0.0, 1.5, 0.0));
            set_emissive(world, glow, [1.0, 0.5, 0.1], 8.0);
            for index in 0..6 {
                let angle = index as f32 / 6.0 * std::f32::consts::TAU;
                let cube = spawn_cube(world, vec3(angle.cos() * 4.0, 0.6, angle.sin() * 4.0));
                set_metallic_roughness(world, cube, 1.0, 0.2);
                set_render_layer(world, cube, 0);
            }

            let light = point_light(world, vec3(3.0, 5.0, 3.0), [1.0, 0.9, 0.8], 40.0);
            set_light_shadows(world, light, true);

            set_bloom(world, true);
            set_bloom_intensity(world, 0.8);
            set_exposure(world, 1.0);
            set_color_grading(world, 1.1, 1.05, 0.0);
            set_tonemap(world, Tonemap::Aces);
            set_depth_of_field(
                world,
                DepthOfField {
                    enabled: true,
                    focus_distance: 8.0,
                    focus_range: 3.0,
                    max_blur_radius: 6.0,
                    bokeh_threshold: 0.8,
                    bokeh_intensity: 1.0,
                    quality: DepthOfFieldQuality::Medium,
                    visualize_coc: false,
                    tilt_shift_enabled: false,
                    tilt_shift_angle: 0.0,
                    tilt_shift_center: 0.0,
                    tilt_shift_blur_amount: 1.0,
                    visualize_tilt_shift: false,
                },
            );

            let camera = orbit_camera(world, vec3(0.0, 1.0, 0.0), 12.0);
            set_camera_layers(world, camera, 0xFFFF_FFFF);

            let label = spawn_text(world, "post fx", ScreenAnchor::TopLeft);
            State {
                bloom: true,
                ssao: false,
                ssr: false,
                ssgi: false,
                taa: false,
                fog: false,
                tonemap: 0,
                shading: 3,
                light,
                label,
            }
        },
        |world, state| {
            if key_pressed(world, KeyCode::Digit1) {
                state.bloom = !state.bloom;
                set_bloom(world, state.bloom);
            }
            if key_pressed(world, KeyCode::Digit2) {
                state.ssao = !state.ssao;
                set_ssao(world, state.ssao);
            }
            if key_pressed(world, KeyCode::Digit3) {
                state.ssr = !state.ssr;
                set_ssr(world, state.ssr);
            }
            if key_pressed(world, KeyCode::Digit4) {
                state.ssgi = !state.ssgi;
                set_ssgi(world, state.ssgi);
            }
            if key_pressed(world, KeyCode::Digit5) {
                state.taa = !state.taa;
                set_taa(world, state.taa);
            }
            if key_pressed(world, KeyCode::Digit6) {
                state.fog = !state.fog;
                set_fog(
                    world,
                    state.fog.then_some(Fog {
                        color: [0.5, 0.6, 0.7],
                        start: 6.0,
                        end: 30.0,
                        mode: Default::default(),
                    }),
                );
            }
            if key_pressed(world, KeyCode::KeyT) {
                let tonemaps = [
                    Tonemap::Aces,
                    Tonemap::Reinhard,
                    Tonemap::Uncharted2,
                    Tonemap::AgX,
                    Tonemap::Neutral,
                ];
                state.tonemap = (state.tonemap + 1) % tonemaps.len();
                set_tonemap(world, tonemaps[state.tonemap]);
            }
            if key_pressed(world, KeyCode::KeyM) {
                let modes = [
                    ShadingMode::Wireframe,
                    ShadingMode::Flat,
                    ShadingMode::Solid,
                    ShadingMode::Rendered,
                ];
                state.shading = (state.shading + 1) % modes.len();
                set_shading_mode(world, modes[state.shading]);
            }
            if key_pressed(world, KeyCode::KeyL) {
                set_light_shadows(world, state.light, false);
            }
            if key_pressed(world, KeyCode::KeyP) {
                std::fs::create_dir_all("screenshots").ok();
                screenshot(world, "screenshots/post_fx.png".into());
            }
            set_text(
                world,
                state.label,
                &format!(
                    "bloom {} ssao {} ssr {} ssgi {} taa {} fog {}",
                    state.bloom, state.ssao, state.ssr, state.ssgi, state.taa, state.fog
                ),
            );
        },
    )
    .unwrap();
}