MAJOR rendering overhaul. Snow deformation, persistent light, flowmap out. Also ECS architexture overhaul

This commit is contained in:
Jonas H
2026-03-03 19:30:41 +01:00
parent f615810509
commit 08ddaa2c5d
56 changed files with 2737 additions and 3463 deletions

139
src/render/shadow.rs Normal file
View File

@@ -0,0 +1,139 @@
use glam::Mat4;
use super::types::{DrawCall, Uniforms, MAX_SPOTLIGHTS};
use super::Renderer;
impl Renderer
{
pub(super) fn render_shadow_pass(
&mut self,
draw_calls: &[DrawCall],
light_view_projections: &[Mat4],
player_position: glam::Vec3,
time: f32,
)
{
let spotlight_count = self.spotlights.len().min(MAX_SPOTLIGHTS);
for layer in 0..spotlight_count
{
let shadow_uniforms = Uniforms::new(
Mat4::IDENTITY,
Mat4::IDENTITY,
light_view_projections[layer],
light_view_projections,
glam::Vec3::ZERO,
player_position,
self.terrain_height_scale,
time,
self.shadow_bias,
2.0,
false,
false,
&self.spotlights,
);
self.queue.write_buffer(
&self.uniform_buffer,
0,
bytemuck::cast_slice(&[shadow_uniforms]),
);
let layer_view = self
.shadow_map_texture
.create_view(&wgpu::TextureViewDescriptor {
dimension: Some(wgpu::TextureViewDimension::D2),
base_array_layer: layer as u32,
array_layer_count: Some(1),
..Default::default()
});
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Shadow Pass Encoder"),
});
{
let mut shadow_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Shadow Pass"),
color_attachments: &[],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: &layer_view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
shadow_pass.set_pipeline(
self.shadow_pipeline
.as_ref()
.expect("shadow pipeline missing"),
);
shadow_pass.set_bind_group(
0,
self.shadow_bind_group
.as_ref()
.expect("shadow bind group missing"),
&[],
);
for draw_call in draw_calls.iter()
{
shadow_pass.set_vertex_buffer(0, draw_call.vertex_buffer.slice(..));
if let Some(ref instance_buffer) = draw_call.instance_buffer
{
shadow_pass.set_vertex_buffer(1, instance_buffer.slice(..));
}
shadow_pass.set_index_buffer(
draw_call.index_buffer.slice(..),
wgpu::IndexFormat::Uint32,
);
shadow_pass.draw_indexed(
0..draw_call.num_indices,
0,
0..draw_call.num_instances,
);
}
}
self.queue.submit(std::iter::once(encoder.finish()));
}
}
pub(super) fn calculate_light_view_projections(&self) -> Vec<Mat4>
{
self.spotlights
.iter()
.take(MAX_SPOTLIGHTS)
.map(|spotlight| {
let light_position = spotlight.position;
let light_target = spotlight.position + spotlight.direction;
let up_vector = if spotlight.direction.y.abs() > 0.99
{
glam::Vec3::Z
}
else
{
glam::Vec3::Y
};
let light_view = Mat4::look_at_rh(light_position, light_target, up_vector);
let fov = spotlight.outer_angle * 2.0;
let near = 0.1;
let far = 150.0;
let light_projection = Mat4::perspective_rh(fov, 1.0, near, far);
light_projection * light_view
})
.collect()
}
}