Implement dynamic atmosphere

https://github.com/Fewes/MinimalAtmosphere
This commit is contained in:
reo 2025-09-18 23:23:53 +03:00
parent 9905ffd26b
commit 7038343b19
9 changed files with 373 additions and 29 deletions

View file

@ -12,7 +12,7 @@ use winit::event::{Event, WindowEvent};
use raidillon_assets::ModelManagerRef;
use raidillon_core::engine::EngineTrait;
use crate::render::debug_ui::ImguiBridge;
use crate::render::BasicMeshRenderingSystem;
use crate::render::{BasicMeshRenderingSystem, SkyAtmosphereRenderingSystem};
use crate::GliumAssetManager;
pub struct GliumPlatform<E: EngineTrait> {
@ -39,6 +39,8 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
let mut rendering_system_manager = RenderingSystemManager::new();
// Install rendering systems
// Draw sky first, then meshes, then debug UI
rendering_system_manager.add::<SkyAtmosphereRenderingSystem>(&display, &window);
rendering_system_manager.add::<BasicMeshRenderingSystem>(&display, &window);
rendering_system_manager.add::<ImguiBridge>(&display, &window);

View file

@ -55,8 +55,9 @@ impl RenderingSystem for BasicMeshRenderingSystem {
}
};
// Direction from the light source (0,+Y) towards the scene.
let light_dir: Vec3 = Vec3::new(0.0, -1.0, 0.0).normalize();
// Match sky light direction: from light towards the scene (upwards +Y)
let light_dir: Vec3 = Vec3::new(0.0, 1.0, 0.0).normalize();
let light_color: [f32; 3] = [1.0, 1.0, 1.0];
// let asset_manager = ctx.asset_manager.borrow();
// let any_ref: &dyn Any = &**asset_manager;
@ -93,7 +94,9 @@ impl RenderingSystem for BasicMeshRenderingSystem {
model: tr.matrix().to_cols_array_2d(),
view: cam.view().to_cols_array_2d(),
projection: cam.projection().to_cols_array_2d(),
u_light: [light_dir.x, light_dir.y, light_dir.z],
camera_pos: [cam.eye.x, cam.eye.y, cam.eye.z],
light_dir: [light_dir.x, light_dir.y, light_dir.z],
light_color: light_color,
tex: sampler,
color: [c[0], c[1], c[2]],
uv_offset: [mat.uv_offset.x, mat.uv_offset.y],

View file

@ -1,4 +1,6 @@
mod basic;
mod sky;
pub mod debug_ui;
pub use basic::BasicMeshRenderingSystem;
pub use basic::BasicMeshRenderingSystem;
pub use sky::SkyAtmosphereRenderingSystem;

View file

@ -0,0 +1,64 @@
use glium::{uniform, Display, Program, Surface};
use glium::glutin::surface::WindowSurface;
use glium::index::NoIndices;
use glium::index::PrimitiveType;
use glium::vertex::EmptyVertexAttributes;
use glam::Mat4;
use crate::system::RenderingContext;
use crate::RenderingSystem;
use raidillon_assets::include_shader;
use raidillon_platform::Camera;
pub struct SkyAtmosphereRenderingSystem {
program: Program,
params: glium::DrawParameters<'static>,
}
impl RenderingSystem for SkyAtmosphereRenderingSystem {
fn initialize(display: &Display<WindowSurface>, _window: &glium::winit::window::Window) -> Self {
const VERT_SRC: &str = include_shader!("sky_atmosphere.vert");
const FRAG_SRC: &str = include_shader!("sky_atmosphere.frag");
let program = Program::from_source(display, VERT_SRC, FRAG_SRC, None).unwrap();
let params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::Overwrite,
write: false,
.. Default::default()
},
backface_culling: glium::draw_parameters::BackfaceCullingMode::CullingDisabled,
.. Default::default()
};
Self { program, params }
}
fn render(&mut self, ctx: &mut RenderingContext) {
let cam = match ctx.scene.world.query::<&Camera>().iter().next() {
Some((_, cam)) => *cam,
None => return,
};
let inv_view: Mat4 = cam.view().inverse();
let inv_proj: Mat4 = cam.projection().inverse();
let light_dir = glam::Vec3::new(0.0, 2.0, 0.0).normalize();
let light_color: [f32; 3] = [1.0, 1.0, 1.0];
let uniforms = uniform! {
inv_view: inv_view.to_cols_array_2d(),
inv_projection: inv_proj.to_cols_array_2d(),
camera_pos: [cam.eye.x, cam.eye.y, cam.eye.z],
light_dir: [light_dir.x, light_dir.y, light_dir.z],
light_color: light_color,
draw_planet: 1.0f32,
};
let vb = EmptyVertexAttributes { len: 3 };
let ib = NoIndices(PrimitiveType::TrianglesList);
ctx.target.draw(vb, &ib, &self.program, &uniforms, &self.params).ok();
}
}