From 105700f55af0fe286282e1774b167c4ea0e8a98e Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 10 May 2025 13:02:54 +1200 Subject: [PATCH 1/4] WIP --- crates/renderling/src/light.rs | 149 +++++++--------- crates/renderling/src/light/cpu.rs | 240 ++++++++++++++------------ crates/renderling/src/light/tiling.rs | 29 ++-- crates/renderling/src/math.rs | 130 +++++++++++++- 4 files changed, 342 insertions(+), 206 deletions(-) diff --git a/crates/renderling/src/light.rs b/crates/renderling/src/light.rs index ad85537..7474bdf 100644 --- a/crates/renderling/src/light.rs +++ b/crates/renderling/src/light.rs @@ -16,7 +16,7 @@ use crate::{ bvol::{Aabb, BoundingSphere}, cubemap::{CubemapDescriptor, CubemapFaceDirection}, geometry::GeometryDescriptor, - math::{Fetch, IsSampler, IsVector, Sample2dArray}, + math::{Fetch, IsAtomicSlab, IsSampler, IsVector, Sample2dArray}, stage::Renderlet, transform::Transform, }; @@ -804,11 +804,6 @@ impl IsDepth for DepthImage2dMultisampled { type Texture = Image!(2D, type=f32, sampled, depth, multisampled=true); } -fn screen_space_to_clip_space(resolution: Vec2, screen_point: Vec2) -> Vec2 { - let normalized = screen_point / resolution; - Vec2::new(normalized.x, 1.0 - normalized.y) * 2.0 - 1.0 -} - /// A tile of screen space used to cull lights. #[derive(Clone, Copy, Default, SlabItem, core::fmt::Debug)] #[offsets] @@ -882,8 +877,10 @@ impl LightTilingInvocation { } /// The index of the fragment within its tile. - // - // TODO: verify this is correct + /// + /// 1. The fragment position is determined from the global invocation index. + /// 2. The fragment's relative xy position within the tile is determined. + /// 3. The index of the fragment's tile position is calculated and returned. fn frag_index(&self) -> usize { // The fragment's xy position within its tile let frag_tile = self.frag_pos() % LightTilingDescriptor::TILE_SIZE; @@ -894,12 +891,12 @@ impl LightTilingInvocation { /// Compute the min and max depth of one fragment/invocation for light tiling. /// /// Returns the **indices** of the min and max depths of the tile. - fn compute_min_and_max_depth( + fn compute_min_and_max_depth( &self, depth_texture: &impl Fetch, _lighting_slab: &[u32], - tiling_slab: &mut [u32], - ) -> (usize, usize) { + tiling_slab: &mut S, + ) -> (Id, Id) { let frag_pos = self.frag_pos(); // Depth frag value at the fragment position let frag_depth: f32 = depth_texture.fetch(frag_pos).x; @@ -913,24 +910,18 @@ impl LightTilingInvocation { let tiling_desc = tiling_slab.read_unchecked(Id::::new(0)); // index of the tile's min depth atomic value in the tiling slab let tile_id = tiling_desc.tiles_array.at(tile_index); - let min_depth_index = (tile_id + LightTile::OFFSET_OF_DEPTH_MIN).index(); + let min_depth_index = tile_id + LightTile::OFFSET_OF_DEPTH_MIN; // index of the tile's max depth atomic value in the tiling slab - let max_depth_index = (tile_id + LightTile::OFFSET_OF_DEPTH_MAX).index(); + let max_depth_index = tile_id + LightTile::OFFSET_OF_DEPTH_MAX; - let _prev_min_depth = unsafe { - spirv_std::arch::atomic_u_min::< - u32, + let _prev_min_depth = tiling_slab.atomic_u_min::< { spirv_std::memory::Scope::Workgroup as u32 }, { spirv_std::memory::Semantics::WORKGROUP_MEMORY.bits() }, - >(&mut tiling_slab[min_depth_index], frag_depth_u32) - }; - let _prev_max_depth = unsafe { - spirv_std::arch::atomic_u_max::< - u32, + >(min_depth_index, frag_depth_u32); + let _prev_max_depth = tiling_slab.atomic_u_max::< { spirv_std::memory::Scope::Workgroup as u32 }, - { spirv_std::memory::Semantics::WORKGROUP_MEMORY.bits() }, - >(&mut tiling_slab[max_depth_index], frag_depth_u32) - }; + { spirv_std::memory::Semantics::WORKGROUP_MEMORY.bits() } + >(max_depth_index, frag_depth_u32); (min_depth_index, max_depth_index) } @@ -949,7 +940,7 @@ impl LightTilingInvocation { && frag_pos.y % LightTilingDescriptor::TILE_SIZE.y == 0 } - fn clear_tiles(&self, tiling_slab: &mut [u32]) { + fn clear_tiles(&self, tiling_slab: &mut S) { if self.frag_pos_is_tile_corner() { // only continue if this is the invocation in the top-left of the tile, as // we only need one invocation per tile. @@ -969,23 +960,26 @@ impl LightTilingInvocation { // index of the tile's max depth atomic value in the tiling slab let max_depth_index = (tile_id + LightTile::OFFSET_OF_DEPTH_MAX).index(); - tiling_slab[min_depth_index] = u32::MAX; - tiling_slab[max_depth_index] = 0; + tiling_slab.write(min_depth_index.into(), &u32::MAX); + tiling_slab.write(max_depth_index.into(), &0u32); } } - fn compute_light_lists( + // The difficulty here is that in SPIRV we can access `tiling_slab` atomically without wrapping it + // in a type, but on CPU we must pass an array of (something like) `AtomicU32`. I'm not sure how to + // model this interaction to test it on the CPU. I think I'll need something like `AtomicSlab`. + fn compute_light_lists( &self, geometry_slab: &[u32], lighting_slab: &[u32], - tiling_slab: &mut [u32], - min_depth_index: usize, - max_depth_index: usize, + tiling_slab: &mut S, + min_depth_index: Id, + max_depth_index: Id, ) { // At this point we know the depth has been computed, so now we can construct the tile's frustum // in clip space. - let depth_min_u32 = tiling_slab[min_depth_index]; - let depth_max_u32 = tiling_slab[max_depth_index]; + let depth_min_u32 = tiling_slab.read_unchecked(min_depth_index); + let depth_max_u32 = tiling_slab.read_unchecked(max_depth_index); let depth_min = depth_min_u32 as f32 / u32::MAX as f32; let depth_max = depth_max_u32 as f32 / u32::MAX as f32; @@ -1011,7 +1005,7 @@ impl LightTilingInvocation { ); let camera = geometry_slab.read_unchecked(camera_id); - let frag_light_index = self.frag_index(); + let index_of_invocation_in_tile = self.frag_index(); // List of all analytical lights in the scene let analytical_lights_array = lighting_slab.read_unchecked( Id::::new(0) @@ -1023,58 +1017,68 @@ impl LightTilingInvocation { // Each invocation will calculate a few lights' contribution to the tile, until all lights // have been visited for step in 0..(analytical_lights_array.len() / count_of_fragments_in_one_tile) + 1 { - let light_index = step * count_of_fragments_in_one_tile + frag_light_index; + let light_index = step * count_of_fragments_in_one_tile + index_of_invocation_in_tile; if light_index >= analytical_lights_array.len() { break; } let light_id = lighting_slab.read_unchecked(analytical_lights_array.at(light_index)); let light = lighting_slab.read_unchecked(light_id); let transform = geometry_slab.read(light.transform_id); - // let should_add = match light.light_type { - // LightStyle::Directional => true, - // LightStyle::Point => { - // let point_light = lighting_slab.read(light.into_point_id()); - // let center = Mat4::from(transform).transform_point3(point_light.position); - // let radius = point_light.radius_of_illumination(1.0); - // let sphere = BoundingSphere::new(center, radius); - // let aabb_ss = sphere.project_onto_viewport(&camera, resolution); - // aabb_ss.intersects_aabb(&tile_aabb_ss) - // } - // LightStyle::Spot => false, - // }; - - // if should_add { - let next_index = unsafe { - spirv_std::arch::atomic_i_increment::< - u32, + let should_add = match light.light_type { + LightStyle::Directional => true, + LightStyle::Point => { + let point_light = lighting_slab.read(light.into_point_id()); + println!("transform: {transform:?}"); + if transform.translation.x.is_nan() { + println!("step: {step}"); + println!("light_index: {light_index}"); + println!("light_id: {light_id:?}"); + println!( + "analytical_lights_array.len: {}", + analytical_lights_array.len() + ); + println!("transform_id: {:?}", light.transform_id); + } + let center = Mat4::from(transform).transform_point3(point_light.position); + let radius = point_light.radius_of_illumination(1.0); + let sphere = BoundingSphere::new(center, radius); + let aabb_ss = sphere.project_onto_viewport(&camera, resolution); + aabb_ss.intersects_aabb(&tile_aabb_ss) + } + LightStyle::Spot => false, + }; + + if should_add { + let next_index = tiling_slab.atomic_i_increment::< { spirv_std::memory::Scope::Workgroup as u32 }, { spirv_std::memory::Semantics::WORKGROUP_MEMORY.bits() }, - >(&mut tiling_slab[(next_light_id).index()]) - }; - if next_index as usize >= tile_lights_array.len() { - break; + >(next_light_id); + if next_index as usize >= tile_lights_array.len() { + break; + } + tiling_slab.write(next_index.into(), &light_id); } - // tiling_slab[next_index as usize] = light_id.inner(); - // } } } // TODO: think about breaking the light tiling "compute tiles" shader up into sub-shaders. // It would also be possible to join or parallelize some of this work with frustum culling // and occlusion culling. - fn compute_tiles( + fn compute_tiles( &self, depth_texture: &impl Fetch, geometry_slab: &[u32], lighting_slab: &[u32], - tiling_slab: &mut [u32], + tiling_slab: &mut S, ) { self.clear_tiles(tiling_slab); + #[cfg(gpu)] unsafe { spirv_std::arch::workgroup_memory_barrier_with_group_sync(); } let (min_index, max_index) = self.compute_min_and_max_depth(depth_texture, lighting_slab, tiling_slab); + #[cfg(gpu)] unsafe { spirv_std::arch::workgroup_memory_barrier_with_group_sync(); } @@ -1205,31 +1209,6 @@ mod test { ); } - #[test] - fn screen_space_to_clip_space_sanity() { - let resolution = Vec2::new(800.0, 600.0); - let tl = Vec2::new(0.0, 0.0); - let tr = Vec2::new(resolution.x, 0.0); - let bl = Vec2::new(0.0, resolution.y); - let br = resolution; - assert_eq!( - Vec2::new(-1.0, 1.0), - screen_space_to_clip_space(resolution, tl) - ); - assert_eq!( - Vec2::new(1.0, 1.0), - screen_space_to_clip_space(resolution, tr) - ); - assert_eq!( - Vec2::new(-1.0, -1.0), - screen_space_to_clip_space(resolution, bl) - ); - assert_eq!( - Vec2::new(1.0, -1.0), - screen_space_to_clip_space(resolution, br) - ); - } - #[test] fn light_tile_fragment_indices() { let descriptor = LightTilingDescriptor { diff --git a/crates/renderling/src/light/cpu.rs b/crates/renderling/src/light/cpu.rs index 929f0cf..bf7f52a 100644 --- a/crates/renderling/src/light/cpu.rs +++ b/crates/renderling/src/light/cpu.rs @@ -452,13 +452,14 @@ mod test { use crate::{ bvol::BoundingBox, camera::Camera, + color::linear_xfer_vec4, draw::DrawIndirectArgs, geometry::GeometryDescriptor, light::{ LightTile, LightTiling, LightTilingDescriptor, LightTilingInvocation, SpotLightCalculation, }, - math::GpuRng, + math::{hex_to_vec4, scaled_f32_to_u8, CpuTexture2d, GpuRng, NonAtomicSlab}, pbr::Material, prelude::Transform, stage::{Renderlet, Stage, Vertex}, @@ -627,7 +628,7 @@ mod test { stage.new_material(Material { albedo_factor: { let mut color = crate::math::hex_to_vec4(albedo_factor); - crate::color::linear_xfer_vec4(&mut color); + linear_xfer_vec4(&mut color); color }, ..Default::default() @@ -685,7 +686,6 @@ mod test { prng: &mut GpuRng, bounding_boxes: &[BoundingBox], ) -> ( - Hybrid, HybridArray, Hybrid, AnalyticalLightBundle, @@ -695,6 +695,9 @@ mod test { while bounding_boxes.iter().any(|bb| bb.contains_point(position)) { position = gen_vec3(prng); } + assert!(!position.x.is_nan()); + assert!(!position.y.is_nan()); + assert!(!position.z.is_nan()); let color = Vec4::new( prng.gen_f32(0.0, 1.0), @@ -710,16 +713,14 @@ mod test { half_extent: Vec3::new(scale, scale, scale) * 0.5, }; - // let inner_cutoff = prng.gen_f32(0.04, 0.09); - // let outer_cutoff = prng.gen_f32(inner_cutoff, 0.16); - // Also make a renderlet for the light, so we can see where it is. + let transform = stage.new_nested_transform(); + transform.modify(|t| { + t.translation = position; + }); let rez = stage .builder() - .with_transform(Transform { - translation: position, - ..Default::default() - }) + .with_transform_id(transform.global_transform_id()) .with_vertices( light_bb .get_mesh() @@ -733,25 +734,16 @@ mod test { ..Default::default() }) .suffix({ + // suffix the actual analytical light let intensity = scale * 100.0; - // let light_descriptor = SpotLightDescriptor { - // position, - // color, - // intensity, - // direction: Vec3::NEG_Y, - // inner_cutoff, - // outer_cutoff, - // }; + let light_descriptor = PointLightDescriptor { - position, + position: Vec3::ZERO, color, intensity, }; - let nested_transform = stage.new_nested_transform(); - nested_transform.modify(|t| { - t.translation = position; - }); - stage.new_analytical_light(light_descriptor, None) + + stage.new_analytical_light(light_descriptor, Some(transform)) }) .build(); rez @@ -778,91 +770,118 @@ mod test { } #[test] - fn light_tiling_positions() { - let w = 32; - let h = 32; - let slab = SlabAllocator::new(CpuRuntime, "test", ()); - let descriptor = slab.new_value(LightTilingDescriptor { - depth_texture_size: UVec2::new(w, h), - ..Default::default() - }); - let tiled_size = descriptor.get().tile_dimensions(); - println!("tiled_size: {tiled_size}"); - let tiles = slab.new_array(vec![ - LightTile::default(); - (tiled_size.x * tiled_size.y) as usize - ]); - descriptor.modify(|d| { - d.tiles_array = tiles.array(); - }); - let desc = descriptor.get(); - let mut tiling_slab = slab.commit().as_vec().clone(); + /// Test the light tiling feature. + fn light_tiling_cpu_sanity() { + let _ = env_logger::builder().is_test(true).try_init(); + let size = size(); + let ctx = crate::Context::headless(size.x, size.y); + let stage = ctx + .new_stage() + .with_lighting(true) + .with_bloom(true) + .with_bloom_mix_strength(0.5); - let mut img = image::RgbImage::new(w, h); - let mut light_img = image::RgbImage::new(w, h); - for x in 0..w { - for y in 0..h { - let global_id = UVec3::new(x, y, 0); - let invocation = LightTilingInvocation::new(global_id, descriptor.get()); - if invocation.should_invoke() { - let pixel = img.get_pixel_mut(x, y); - let r = (x as f32 / w as f32 * 255.0) as u8; - let g = (y as f32 / h as f32 * 255.0) as u8; - pixel.0 = [r, g, 0x00]; - - if invocation.frag_pos_is_tile_corner() { - pixel.0[0] = 0xFF - pixel.0[0]; - pixel.0[1] = 0xFF - pixel.0[1]; - pixel.0[2] = 0xFF - pixel.0[2]; - - let tile_dimensions = tiled_size; - let tile_index = invocation.tile_index(); - println!("frag_pos: {}", invocation.frag_pos()); - println!("tile_pos: {}", invocation.tile_pos()); - println!("tile_index: {tile_index}"); - let num_tiles = tile_dimensions.x * tile_dimensions.y; - - // index of the tile's min depth atomic value in the tiling slab - let min_depth_index = (invocation.descriptor.tiles_array.at(tile_index) - + LightTile::OFFSET_OF_DEPTH_MIN) - .index(); - // index of the tile's max depth atomic value in the tiling slab - let max_depth_index = (invocation.descriptor.tiles_array.at(tile_index) - + LightTile::OFFSET_OF_DEPTH_MAX) - .index(); - - let percent = tile_index as f32 / num_tiles as f32; //frag_pos.x as f32 / self.descriptor.depth_texture_size.x as f32; - tiling_slab[min_depth_index] = (percent * u32::MAX as f32) as u32; - tiling_slab[max_depth_index] = u32::MAX; //(percent * u32::MAX as f32) as u32; - } + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("light_tiling_test.glb"), + ) + .unwrap(); + + let camera = stage.new_camera(make_camera()); + stage.use_camera(camera); + + let moonlight = doc.lights.first().unwrap(); + let _shadow = { + let sm = stage + .new_shadow_map(moonlight, UVec2::splat(1024), 0.1, 256.0) + .unwrap(); + sm.shadowmap_descriptor.modify(|d| { + d.bias_min = 0.0; + d.bias_max = 0.0; + d.pcf_samples = 2; + }); + sm.update(&stage, doc.renderlets_iter()).unwrap(); + sm + }; - let pixel = light_img.get_pixel_mut(x, y); - let index = invocation.frag_index(); - println!("index: {index}"); - let value = crate::math::scaled_f32_to_u8(index as f32 / (16.0 * 16.0)); - pixel.0[0] = value; - pixel.0[1] = value; - pixel.0[2] = value; + let mut bounding_boxes = vec![]; + for node in doc.nodes.iter() { + if node.mesh.is_none() { + continue; + } + let transform = Mat4::from(node.transform.get_global_transform()); + if let Some(mesh_index) = node.mesh { + let mesh = &doc.meshes[mesh_index]; + for prim in mesh.primitives.iter() { + let (min, max) = prim.bounding_box; + let min = transform.transform_point3(min); + let max = transform.transform_point3(max); + let bb = BoundingBox::from_min_max(min, max); + if bb.half_extent.min_element().is_zero() { + continue; + } + bounding_boxes.push(bb); } } } - img_diff::save("light/tiling/positions.png", img); - img_diff::save("light/tiling/frag_pos.png", light_img); - let (mins, maxs) = tiling_slab - .read_vec(desc.tiles_array) - .into_iter() - .map(|tile| { - ( - crate::math::scaled_u32_to_u8(tile.depth_min), - crate::math::scaled_u32_to_u8(tile.depth_max), - ) - }) - .unzip(); - let mins_img = image::GrayImage::from_vec(tiled_size.x, tiled_size.y, mins).unwrap(); - img_diff::save("light/tiling/positions-mins.png", mins_img); - let maxs_img = image::GrayImage::from_vec(tiled_size.x, tiled_size.y, maxs).unwrap(); - img_diff::save("light/tiling/positions-maxs.png", maxs_img); + let mut prng = crate::math::GpuRng::new(666); + let mut lights = vec![]; + + for _ in 0..MAX_LIGHTS { + lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); + } + + // Remove the light meshes + for (_, _, _, renderlet) in lights.iter() { + stage.remove_renderlet(renderlet); + } + snapshot( + &ctx, + &stage, + "light/tiling/cpu/4-after-lights-no-meshes.png", + ); + + // Get all the slabs and run the shader on the CPU + + let tiling = LightTiling::new(ctx.runtime(), false, size, 32); + let desc = tiling.descriptor().get(); + let depth = stage.depth_texture.read().unwrap(); + let depth_img = crate::texture::read_depth_texture_to_image( + ctx.runtime(), + size.x as usize, + size.y as usize, + &depth.texture, + ) + .unwrap(); + let geometry_slab = + futures_lite::future::block_on(stage.geometry.slab_allocator().read(..)).unwrap(); + let lighting_slab = + futures_lite::future::block_on(stage.lighting.slab_allocator().read(..)).unwrap(); + let tiling_slab = { + tiling.prepare(UVec2::new(depth_img.width(), depth_img.height())); + let _ = tiling.tiling_slab.commit(); + futures_lite::future::block_on(tiling.tiling_slab.read(..)).unwrap() + }; + + let w = depth_img.width() / LightTilingDescriptor::TILE_SIZE.x + 1; + let h = depth_img.height() / LightTilingDescriptor::TILE_SIZE.y + 1; + let mut non_atomic_tiling_slab = NonAtomicSlab::new(tiling_slab); + let depth_img = CpuTexture2d::from_image(depth_img, crate::math::luma_u8_to_vec4); + for x in 0..w { + for y in 0..h { + let global_id = UVec3::new(x, y, 0); + let invocation = LightTilingInvocation::new(global_id, desc); + invocation.compute_tiles( + &depth_img, + &geometry_slab, + &lighting_slab, + &mut non_atomic_tiling_slab, + ); + } + } } #[test] @@ -935,15 +954,20 @@ mod test { log::info!("have {} bounding boxes", bounding_boxes.len()); let mut prng = crate::math::GpuRng::new(666); - let mut lights = vec![]; - - for _ in 0..MAX_LIGHTS { + let mut lights: Vec<( + HybridArray, + Hybrid, + AnalyticalLightBundle, + Hybrid, + )> = vec![]; + + for _ in 0..MAX_LIGHTS / 2 { lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); } snapshot(&ctx, &stage, "light/tiling/3-after-lights.png"); // Remove the light meshes - for (_, _, _, _, renderlet) in lights.iter() { + for (_, _, _, renderlet) in lights.iter() { stage.remove_renderlet(renderlet); } snapshot(&ctx, &stage, "light/tiling/4-after-lights-no-meshes.png"); @@ -995,7 +1019,7 @@ mod test { iterations: vec![], }; - for (i, (_, _, _, light, _)) in lights.iter().enumerate() { + for (i, (_, _, light, _)) in lights.iter().enumerate() { stage.remove_light(light); if i < number_of_lights { stage.add_light(light); diff --git a/crates/renderling/src/light/tiling.rs b/crates/renderling/src/light/tiling.rs index 68becbb..9a9c571 100644 --- a/crates/renderling/src/light/tiling.rs +++ b/crates/renderling/src/light/tiling.rs @@ -9,12 +9,11 @@ use std::sync::Arc; use craballoc::{ runtime::WgpuRuntime, - slab::{SlabAllocator, SlabAllocatorError, SlabBuffer}, + slab::{SlabAllocator, SlabBuffer}, value::{GpuArray, Hybrid}, }; -use crabslab::{Id, Slab}; +use crabslab::Id; use glam::UVec2; -use snafu::OptionExt; use crate::bindgroup::ManagedBindGroup; @@ -22,9 +21,9 @@ use super::{LightTile, LightTilingDescriptor}; pub struct LightTiling { // depth_pre_pass_pipeline: Arc, - tiling_slab: SlabAllocator, + pub(crate) tiling_slab: SlabAllocator, tiling_descriptor: Hybrid, - tiles: GpuArray, + _tiles: GpuArray, bind_group_creation_time: Arc, depth_texture_id: Arc, compute_tiles_bind_group_layout: Arc, @@ -148,7 +147,7 @@ impl LightTiling { Self { tiling_slab, tiling_descriptor, - tiles, + _tiles: tiles, bind_group_creation_time: Default::default(), depth_texture_id: Default::default(), compute_tiles_bind_group_layout: compute_tiles_bind_group_layout.into(), @@ -157,17 +156,22 @@ impl LightTiling { } } + pub(crate) fn prepare(&self, depth_texture_size: UVec2) { + self.tiling_descriptor.modify(|d| { + d.depth_texture_size = depth_texture_size; + }); + } + pub fn run( &self, geometry_slab: &SlabBuffer, lighting_slab: &SlabBuffer, depth_texture: &crate::texture::Texture, ) { + let depth_texture_size = depth_texture.size(); + self.prepare(depth_texture_size); + let runtime = self.tiling_slab.runtime(); - let depth_texture_size = self.tiling_descriptor.modify(|d| { - d.depth_texture_size = depth_texture.size(); - d.depth_texture_size - }); let tiling_slab_buffer = self.tiling_slab.commit(); let label = Some("light-tiling-compute-tiles"); let mut encoder = runtime @@ -226,8 +230,8 @@ impl LightTiling { }); compute_pass.set_bind_group(0, bind_group.as_ref(), &[]); - let x = depth_texture_size.x / 16 + 1; - let y = depth_texture_size.y / 16 + 1; + let x = depth_texture_size.x / LightTilingDescriptor::TILE_SIZE.x + 1; + let y = depth_texture_size.y / LightTilingDescriptor::TILE_SIZE.y + 1; let z = 1; compute_pass.dispatch_workgroups(x, y, z); } @@ -238,6 +242,7 @@ impl LightTiling { pub(crate) async fn read_images( &self, ) -> (image::GrayImage, image::GrayImage, image::GrayImage) { + use crabslab::Slab; let size = self.tiling_descriptor.get().depth_texture_size / 16; let slab = self.tiling_slab.read(..).await.unwrap(); log::info!("tiling slab size: {}", slab.len()); diff --git a/crates/renderling/src/math.rs b/crates/renderling/src/math.rs index cd677c6..ff910da 100644 --- a/crates/renderling/src/math.rs +++ b/crates/renderling/src/math.rs @@ -6,11 +6,18 @@ //! run on the CPU. //! //! Lastly, it provides some constant geometry used in many shaders. -use core::ops::Mul; +use core::{ + marker::PhantomData, + ops::{IndexMut, Mul}, + sync::atomic::AtomicU32, +}; +use crabslab::{Id, Slab}; use spirv_std::{ image::{sample_with, Cubemap, Image2d, Image2dArray, ImageWithMethods}, + integer::Integer, Image, Sampler, }; +use std::sync::RwLock; pub use glam::*; pub use spirv_std::num_traits::{clamp, Float, Zero}; @@ -103,6 +110,122 @@ impl SampleCube for Cubemap { } } +/// Abstraction over shader atomic integer operations. +pub trait IsAtomicSlab: Slab { + /// Perform the following steps atomically with respect to any other atomic + /// accesses within `SCOPE` to the same location: + /// + /// 1. Load through `id` to get an original value, + /// 2. Get a new value through integer addition of 1 to original value, and + /// 3. Store the new value back through `id`. + /// + /// The result is the original value. + fn atomic_i_increment(&mut self, id: Id) -> u32; + fn atomic_u_min( + &mut self, + id: Id, + val: u32, + ) -> u32; + fn atomic_u_max( + &mut self, + id: Id, + val: u32, + ) -> u32; +} + +impl IsAtomicSlab for [u32] { + fn atomic_i_increment(&mut self, id: Id) -> u32 { + let ptr = &mut self[id.index()]; + unsafe { spirv_std::arch::atomic_i_increment::(ptr) } + } + + fn atomic_u_min( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self[id.index()]; + unsafe { spirv_std::arch::atomic_u_min::(ptr, val) } + } + + fn atomic_u_max( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self[id.index()]; + unsafe { spirv_std::arch::atomic_u_max::(ptr, val) } + } +} + +#[cfg(cpu)] +/// A slab for testing that is **not** atomic. +pub struct NonAtomicSlab { + inner: T, +} + +impl NonAtomicSlab { + pub fn new(inner: T) -> Self { + NonAtomicSlab { inner } + } +} + +#[cfg(cpu)] +impl Slab for NonAtomicSlab { + fn len(&self) -> usize { + self.inner.len() + } + + fn read_unchecked(&self, id: Id) -> T { + self.inner.read_unchecked(id) + } + + fn write_indexed(&mut self, t: &T, index: usize) -> usize { + self.inner.write_indexed(t, index) + } + + fn write_indexed_slice(&mut self, t: &[T], index: usize) -> usize { + self.inner.write_indexed_slice(t, index) + } +} + +#[cfg(cpu)] +impl IsAtomicSlab for NonAtomicSlab +where + S: Slab + IndexMut, +{ + fn atomic_i_increment(&mut self, id: Id) -> u32 { + let ptr = &mut self.inner[id.index()]; + let i = *ptr; + *ptr = i + 1; + i + } + + fn atomic_u_min( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self.inner[id.index()]; + let original = *ptr; + let new = original.min(val); + *ptr = new; + original + } + + fn atomic_u_max( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self.inner[id.index()]; + let original = *ptr; + let new = original.max(val); + *ptr = new; + original + } +} + #[cfg(not(target_arch = "spirv"))] mod cpu { @@ -257,6 +380,11 @@ mod cpu { u as f32 / 255.0 } + pub fn luma_u8_to_vec4(p: &image::Luma) -> Vec4 { + let shade = scaled_u8_to_f32(p.0[0]); + Vec3::splat(shade).extend(1.0) + } + /// Convert an f32 in range 0.0 - 1.0 into a u8 in range 0-255. pub fn scaled_f32_to_u8(f: f32) -> u8 { (f * 255.0) as u8 From 9ff0b765da320b52a3fb1bca886ca6bc7d77a32e Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sun, 11 May 2025 08:31:24 +1200 Subject: [PATCH 2/4] pedastal scene --- blender/pedistal.blend | Bin 0 -> 540532 bytes .../light-light_tiling_compute_tiles.spv | Bin 6668 -> 20252 bytes ...ight_tiling_compute_tiles_multisampled.spv | Bin 6680 -> 20264 bytes .../shaders/stage-renderlet_fragment.spv | Bin 104896 -> 104896 bytes crates/renderling/src/light.rs | 12 +- crates/renderling/src/light/cpu.rs | 124 ++++++++++++++++-- crates/renderling/src/light/shadow_map.rs | 3 +- crates/renderling/src/math.rs | 122 ++++++++--------- crates/renderling/src/pbr.rs | 7 +- gltf/pedastal.glb | Bin 0 -> 2236 bytes 10 files changed, 189 insertions(+), 79 deletions(-) create mode 100644 blender/pedistal.blend create mode 100644 gltf/pedastal.glb diff --git a/blender/pedistal.blend b/blender/pedistal.blend new file mode 100644 index 0000000000000000000000000000000000000000..a81f0b8d82e11244b59cdb952b7c83b0e34956b7 GIT binary patch literal 540532 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 z

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 UIQvYn57LU3D^iF6{^#HS0W7Vlp8x;= literal 0 HcmV?d00001 diff --git a/crates/renderling/shaders/light-light_tiling_compute_tiles.spv b/crates/renderling/shaders/light-light_tiling_compute_tiles.spv index 5fc27659f36912bcb42e15e645b4e69c85f23edf..381a54b1f047d9b7393a2779e0c7b9eba0dc210b 100644 GIT binary patch literal 20252 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 diff --git a/crates/renderling/shaders/light-light_tiling_compute_tiles_multisampled.spv b/crates/renderling/shaders/light-light_tiling_compute_tiles_multisampled.spv index 11ca70bda5ff7292cb4f7c8b2caf7b6bbde1fcd4..af944ec0c29e3c1e47d9a08043c1d6593f7a4001 100644 GIT binary patch literal 20264 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 L|H+EpHs${V7f;Pa literal 104896 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 NqpSaw6}@}P{{!%X%ew#o diff --git a/crates/renderling/src/light.rs b/crates/renderling/src/light.rs index 7474bdf..ec94ddf 100644 --- a/crates/renderling/src/light.rs +++ b/crates/renderling/src/light.rs @@ -1028,16 +1028,16 @@ impl LightTilingInvocation { LightStyle::Directional => true, LightStyle::Point => { let point_light = lighting_slab.read(light.into_point_id()); - println!("transform: {transform:?}"); + crate::println!("transform: {transform:?}"); if transform.translation.x.is_nan() { - println!("step: {step}"); - println!("light_index: {light_index}"); - println!("light_id: {light_id:?}"); - println!( + crate::println!("step: {step}"); + crate::println!("light_index: {light_index}"); + crate::println!("light_id: {light_id:?}"); + crate::println!( "analytical_lights_array.len: {}", analytical_lights_array.len() ); - println!("transform_id: {:?}", light.transform_id); + crate::println!("transform_id: {:?}", light.transform_id); } let center = Mat4::from(transform).transform_point3(point_light.position); let radius = point_light.radius_of_illumination(1.0); diff --git a/crates/renderling/src/light/cpu.rs b/crates/renderling/src/light/cpu.rs index bf7f52a..2bb68b7 100644 --- a/crates/renderling/src/light/cpu.rs +++ b/crates/renderling/src/light/cpu.rs @@ -437,7 +437,7 @@ mod test { use craballoc::runtime::CpuRuntime; use crabslab::{Array, CpuSlab, Slab}; - use glam::{UVec3, Vec3, Vec4, Vec4Swizzles}; + use glam::{UVec3, Vec2, Vec3, Vec4, Vec4Swizzles}; use plotters::{ chart::{ChartBuilder, SeriesLabelPosition}, prelude::{ @@ -459,7 +459,7 @@ mod test { LightTile, LightTiling, LightTilingDescriptor, LightTilingInvocation, SpotLightCalculation, }, - math::{hex_to_vec4, scaled_f32_to_u8, CpuTexture2d, GpuRng, NonAtomicSlab}, + math::{hex_to_vec4, scaled_f32_to_u8, ConstTexture, CpuTexture2d, GpuRng, NonAtomicSlab}, pbr::Material, prelude::Transform, stage::{Renderlet, Stage, Vertex}, @@ -686,6 +686,7 @@ mod test { prng: &mut GpuRng, bounding_boxes: &[BoundingBox], ) -> ( + Hybrid, HybridArray, Hybrid, AnalyticalLightBundle, @@ -720,7 +721,10 @@ mod test { }); let rez = stage .builder() - .with_transform_id(transform.global_transform_id()) + .with_transform(Transform { + translation: position, + ..Default::default() + }) .with_vertices( light_bb .get_mesh() @@ -738,12 +742,12 @@ mod test { let intensity = scale * 100.0; let light_descriptor = PointLightDescriptor { - position: Vec3::ZERO, + position, color, intensity, }; - stage.new_analytical_light(light_descriptor, Some(transform)) + stage.new_analytical_light(light_descriptor, None) }) .build(); rez @@ -835,7 +839,7 @@ mod test { } // Remove the light meshes - for (_, _, _, renderlet) in lights.iter() { + for (_, _, _, _, renderlet) in lights.iter() { stage.remove_renderlet(renderlet); } snapshot( @@ -955,19 +959,20 @@ mod test { let mut prng = crate::math::GpuRng::new(666); let mut lights: Vec<( + Hybrid, HybridArray, Hybrid, AnalyticalLightBundle, Hybrid, )> = vec![]; - for _ in 0..MAX_LIGHTS / 2 { + for _ in 0..MAX_LIGHTS { lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); } snapshot(&ctx, &stage, "light/tiling/3-after-lights.png"); // Remove the light meshes - for (_, _, _, renderlet) in lights.iter() { + for (_, _, _, _, renderlet) in lights.iter() { stage.remove_renderlet(renderlet); } snapshot(&ctx, &stage, "light/tiling/4-after-lights-no-meshes.png"); @@ -1019,7 +1024,7 @@ mod test { iterations: vec![], }; - for (i, (_, _, light, _)) in lights.iter().enumerate() { + for (i, (_, _, _, light, _)) in lights.iter().enumerate() { stage.remove_light(light); if i < number_of_lights { stage.add_light(light); @@ -1145,4 +1150,105 @@ mod test { .unwrap(); root_drawing_area.present().unwrap(); } + + #[test] + /// Ensures that a point light with a translated position renders the same + /// as a point light at the origin that has a transform applied with + /// that same translation. + /// + /// In other words, light in nested transform is the same as light + fn point_light_transform() { + let ctx = crate::Context::headless(256, 256); + let stage = ctx + .new_stage() + .with_lighting(false) + .with_bloom_mix_strength(0.08); + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("pedastal.glb"), + ) + .unwrap(); + let camera = doc.cameras.first().unwrap(); + camera.camera.modify(|cam| { + cam.set_projection(Mat4::perspective_rh( + std::f32::consts::FRAC_PI_6, + 1.0, + 0.1, + 15.0, + )); + }); + + let color = { + let mut c = hex_to_vec4(0xEEDF7AFF); + linear_xfer_vec4(&mut c); + c + }; + let position = Vec3::new(0.0, 1.0, 0.0); + let transform = stage.new_nested_transform(); + transform.modify(|t| t.translation = position); + + stage.set_has_lighting(true); + // let _dir_light = stage.new_analytical_light( + // DirectionalLightDescriptor { + // direction: Vec3::NEG_Y, + // color, + // intensity: 1.0, + // }, + // None, + // ); + // snapshot(&ctx, &stage, "light/point/transform-direction.png"); + + let bb = BoundingBox { + center: Vec3::ZERO, + half_extent: Vec3::splat(0.25), + }; + let _light_mesh_rez = stage + .builder() + .with_transform_id(transform.global_transform_id()) + .with_vertices( + bb.get_mesh() + .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)), + ) + .with_material(Material { + albedo_factor: color, + emissive_factor: color.xyz(), + emissive_strength_multiplier: 4.0, + ..Default::default() + }) + .build(); + + let light_descriptor = PointLightDescriptor { + position: Vec3::ZERO, + color, + intensity: 10.0, + }; + let _light = stage.new_analytical_light(light_descriptor, Some(transform)); + snapshot(&ctx, &stage, "light/point/pedastal.png"); + + // light.transform.modify(|t| t.translation = position); + + // snapshot(&ctx, &stage, "light/point/transform-nest.png"); + + // let light_slab = + // futures_lite::future::block_on(stage.lighting.light_slab.read(..)).unwrap(); + // let frag = crate::pbr::shade_fragment( + // &ConstTexture::new(Vec4::ZERO), + // &(), + // camera.node_transform.get_global_transform().translation, + // Vec3::Y, + // Vec3::ZERO, + // Vec3::splat(0.5), + // 0.0, + // 1.0, + // 0.0, + // Vec3::ZERO, + // Vec3::ONE, + // Vec3::ONE, + // Vec2::ONE, + // &light_slab, + // ); + // println!("frag: {frag}"); + } } diff --git a/crates/renderling/src/light/shadow_map.rs b/crates/renderling/src/light/shadow_map.rs index c6dfe5e..a03b426 100644 --- a/crates/renderling/src/light/shadow_map.rs +++ b/crates/renderling/src/light/shadow_map.rs @@ -642,9 +642,10 @@ mod test { let mut shadows = vec![]; let z_near = 0.1; let z_far = 100.0; - for (_i, light_bundle) in doc.lights.iter().enumerate() { + for (i, light_bundle) in doc.lights.iter().enumerate() { { let desc = light_bundle.light_details.as_point().unwrap().get(); + println!("point light {i}: {:?}", desc); let (p, vs) = desc.shadow_mapping_projection_and_view_matrices( &light_bundle.transform.get_global_transform().into(), z_near, diff --git a/crates/renderling/src/math.rs b/crates/renderling/src/math.rs index ff910da..f22cde8 100644 --- a/crates/renderling/src/math.rs +++ b/crates/renderling/src/math.rs @@ -6,18 +6,12 @@ //! run on the CPU. //! //! Lastly, it provides some constant geometry used in many shaders. -use core::{ - marker::PhantomData, - ops::{IndexMut, Mul}, - sync::atomic::AtomicU32, -}; +use core::ops::{IndexMut, Mul}; use crabslab::{Id, Slab}; use spirv_std::{ image::{sample_with, Cubemap, Image2d, Image2dArray, ImageWithMethods}, - integer::Integer, Image, Sampler, }; -use std::sync::RwLock; pub use glam::*; pub use spirv_std::num_traits::{clamp, Float, Zero}; @@ -159,73 +153,81 @@ impl IsAtomicSlab for [u32] { } #[cfg(cpu)] -/// A slab for testing that is **not** atomic. -pub struct NonAtomicSlab { - inner: T, -} +mod non_atomic { + use super::*; -impl NonAtomicSlab { - pub fn new(inner: T) -> Self { - NonAtomicSlab { inner } + /// A slab for testing that is **not** atomic. + pub struct NonAtomicSlab { + inner: T, } -} -#[cfg(cpu)] -impl Slab for NonAtomicSlab { - fn len(&self) -> usize { - self.inner.len() + impl NonAtomicSlab { + pub fn new(inner: T) -> Self { + NonAtomicSlab { inner } + } } - fn read_unchecked(&self, id: Id) -> T { - self.inner.read_unchecked(id) - } + impl Slab for NonAtomicSlab { + fn len(&self) -> usize { + self.inner.len() + } - fn write_indexed(&mut self, t: &T, index: usize) -> usize { - self.inner.write_indexed(t, index) - } + fn read_unchecked(&self, id: Id) -> T { + self.inner.read_unchecked(id) + } - fn write_indexed_slice(&mut self, t: &[T], index: usize) -> usize { - self.inner.write_indexed_slice(t, index) - } -} + fn write_indexed(&mut self, t: &T, index: usize) -> usize { + self.inner.write_indexed(t, index) + } -#[cfg(cpu)] -impl IsAtomicSlab for NonAtomicSlab -where - S: Slab + IndexMut, -{ - fn atomic_i_increment(&mut self, id: Id) -> u32 { - let ptr = &mut self.inner[id.index()]; - let i = *ptr; - *ptr = i + 1; - i + fn write_indexed_slice(&mut self, t: &[T], index: usize) -> usize { + self.inner.write_indexed_slice(t, index) + } } - fn atomic_u_min( - &mut self, - id: Id, - val: u32, - ) -> u32 { - let ptr = &mut self.inner[id.index()]; - let original = *ptr; - let new = original.min(val); - *ptr = new; - original - } + impl IsAtomicSlab for NonAtomicSlab + where + S: Slab + IndexMut, + { + fn atomic_i_increment( + &mut self, + id: Id, + ) -> u32 { + let ptr = &mut self.inner[id.index()]; + let i = *ptr; + *ptr = i + 1; + i + } - fn atomic_u_max( - &mut self, - id: Id, - val: u32, - ) -> u32 { - let ptr = &mut self.inner[id.index()]; - let original = *ptr; - let new = original.max(val); - *ptr = new; - original + fn atomic_u_min( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self.inner[id.index()]; + let original = *ptr; + let new = original.min(val); + *ptr = new; + original + } + + fn atomic_u_max( + &mut self, + id: Id, + val: u32, + ) -> u32 { + let ptr = &mut self.inner[id.index()]; + let original = *ptr; + let new = original.max(val); + *ptr = new; + original + } } } +#[cfg(cpu)] +pub use non_atomic::*; + #[cfg(not(target_arch = "spirv"))] mod cpu { diff --git a/crates/renderling/src/pbr.rs b/crates/renderling/src/pbr.rs index ef561fc..b7c306a 100644 --- a/crates/renderling/src/pbr.rs +++ b/crates/renderling/src/pbr.rs @@ -574,8 +574,8 @@ where let lighting_desc = light_slab.read_unchecked(Id::::new(0)); let analytical_lights_array = lighting_desc.analytical_lights_array; my_println!("lights: {analytical_lights_array:?}"); - my_println!("n: {n:?}"); - my_println!("v: {v:?}"); + my_println!("surface normal: {n:?}"); + my_println!("vector from surface to camera: {v:?}"); // accumulated outgoing radiance let mut lo = Vec3::ZERO; @@ -595,9 +595,10 @@ where intensity, } = light_slab.read(light.into_point_id()); let position = transform.transform_point3(position); - let frag_to_light = position - in_pos; + let frag_to_light = in_pos - position; // - in_pos; let distance = frag_to_light.length(); if distance == 0.0 { + crate::println!("distance between point light and surface is zero"); continue; } let l = frag_to_light.alt_norm_or_zero(); diff --git a/gltf/pedastal.glb b/gltf/pedastal.glb new file mode 100644 index 0000000000000000000000000000000000000000..af2ef06e04cc8470d8d731e5708e88f2d00edf33 GIT binary patch literal 2236 zcmb7EZI2T-5H?WYN?RyU+OLs6FN?kJ&IgVofO_rSrAkf+>4eH=~l`i@YFWD2s#}iojvM?|@PW z$V?S+R!$6jXuEzC32+Iy!x7uFg&(<0@DMbvh&(H>A#^BM7zLr{^1#z4tkPdAM#tno zgA&eUqS7;{5#9tcJ&Z})+zvN}MbAh185F{Hh44iH>9fe;%ne+NejLScZ=6B(KV}m5 z%mz*m?g_?uz#X_Gbw0!UXhz0+n8r#LX*{X&9Om=EME2969MZNb<`OQdy2r!X&Ss25 z56lL|p;Yl?k|w=;K0eK42?z^1h)dbYCwcKIPIN<^Fx!VZSCeDF+RYfS3!Mfuf$oo0 z*)Q?-oajv;w@dK-z=6c)Zkpn1DTB#yk#efz!n7E(MbPdpf^=qjPY;ddhp!vbyrwl z_tjwE>dgg|r5V`|@gUzAJKS&%12{+1*}W`6U4X`^;ZZ_EwSK=r$n*Up_}eabVL|%u z)qAb4ZN9YEIDogp+_E=u&}Qo%VrU$osQ=P_l|yZ}jn}@r4V*3eRSpKHwlVT5gLMpp zYjlR94~`WDtj*D^4eAWvv@^0RaZIc_hOu44F*X}?&Bpi}TH9{5*@DwTKbV{J)6+`6 zNzrZzx=o69DBq-L_YCGcm;|Qb(GKMVD9R0wdK~Y7E Date: Sun, 18 May 2025 08:12:01 +1200 Subject: [PATCH 3/4] rename pedestal asset --- Cargo.toml | 1 + blender/{pedistal.blend => pedestal.blend} | Bin 540532 -> 554324 bytes gltf/pedastal.glb | Bin 2236 -> 0 bytes gltf/pedestal.glb | Bin 0 -> 49080 bytes 4 files changed, 1 insertion(+) rename blender/{pedistal.blend => pedestal.blend} (56%) delete mode 100644 gltf/pedastal.glb create mode 100644 gltf/pedestal.glb diff --git a/Cargo.toml b/Cargo.toml index 66e32ba..d8df9e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ serde_json = "1.0.117" send_wrapper = "0.6.0" snafu = "0.8" spirv-std = { git = "https://github.com/LegNeato/rust-gpu.git", rev = "16b61ce" } +spirv-std-macros = { git = "https://github.com/LegNeato/rust-gpu.git", rev = "16b61ce" } syn = { version = "2.0.49", features = ["full", "extra-traits", "parsing"] } tracing = "0.1.41" wasm-bindgen = "0.2" diff --git a/blender/pedistal.blend b/blender/pedestal.blend similarity index 56% rename from blender/pedistal.blend rename to blender/pedestal.blend index a81f0b8d82e11244b59cdb952b7c83b0e34956b7..65f645d346718da28264648a2131861b466158b8 100644 GIT binary patch delta 72190 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 delta 60310 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

    3I*$Zw~`SmIgUiWUo;{#}w) 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 diff --git a/gltf/pedastal.glb b/gltf/pedastal.glb deleted file mode 100644 index af2ef06e04cc8470d8d731e5708e88f2d00edf33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2236 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 jkA5S(8y*3D1bOuDLeGYGK;J(** literal 0 HcmV?d00001 From 8730f76dd679dd7c6105b181b2cb2151a4b4ac79 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sun, 18 May 2025 10:35:34 +1200 Subject: [PATCH 4/4] fixed renderlet bindgroup invalidation bug, moved lighting tests to their own module --- crates/renderling/src/light.rs | 10 + crates/renderling/src/light/cpu.rs | 970 +++--------------------- crates/renderling/src/light/cpu/test.rs | 825 ++++++++++++++++++++ crates/renderling/src/light/tiling.rs | 6 +- crates/renderling/src/stage/cpu.rs | 29 +- 5 files changed, 969 insertions(+), 871 deletions(-) create mode 100644 crates/renderling/src/light/cpu/test.rs diff --git a/crates/renderling/src/light.rs b/crates/renderling/src/light.rs index ec94ddf..9370a03 100644 --- a/crates/renderling/src/light.rs +++ b/crates/renderling/src/light.rs @@ -433,6 +433,16 @@ pub enum LightStyle { Spot = 2, } +impl core::fmt::Display for LightStyle { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + LightStyle::Directional => f.write_str("directional"), + LightStyle::Point => f.write_str("point"), + LightStyle::Spot => f.write_str("spot"), + } + } +} + impl SlabItem for LightStyle { const SLAB_SIZE: usize = { 1 }; diff --git a/crates/renderling/src/light/cpu.rs b/crates/renderling/src/light/cpu.rs index 2bb68b7..6ebcab5 100644 --- a/crates/renderling/src/light/cpu.rs +++ b/crates/renderling/src/light/cpu.rs @@ -1,6 +1,7 @@ //! CPU-only lighting and shadows. -use std::sync::{Arc, Mutex, RwLock}; +use core::ops::Deref; +use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard}; use craballoc::{ prelude::{Hybrid, SlabAllocator, WgpuRuntime}, @@ -128,6 +129,16 @@ pub struct AnalyticalLightBundle { pub transform: NestedTransform, } +impl core::fmt::Display for AnalyticalLightBundle { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!( + "{} {:?}", + self.light_details.style(), + self.light.id() + )) + } +} + impl Clone for AnalyticalLightBundle where Ct::Container: Clone, @@ -192,6 +203,20 @@ impl AnalyticalLightBundle { } } +struct AnalyticalLightIterator<'a> { + inner: RwLockReadGuard<'a, Vec>>, + index: usize, +} + +impl Iterator for AnalyticalLightIterator<'_> { + type Item = AnalyticalLightBundle; + + fn next(&mut self) -> Option { + let item = self.inner.get(self.index)?; + item.upgrade() + } +} + /// Manages lighting for an entire scene. #[derive(Clone)] pub struct Lighting { @@ -200,8 +225,8 @@ pub struct Lighting { pub(crate) light_slab_buffer: Arc>>, pub(crate) geometry_slab_buffer: Arc>>, pub(crate) lighting_descriptor: Hybrid, - pub(crate) analytical_lights: Arc>>>, - pub(crate) analytical_lights_array: Arc>>>, + pub(crate) analytical_lights: Arc>>>, + pub(crate) analytical_lights_array: Arc>>>>, pub(crate) shadow_map_update_pipeline: Arc, pub(crate) shadow_map_update_bindgroup_layout: Arc, pub(crate) shadow_map_update_blitter: AtlasBlitter, @@ -279,7 +304,7 @@ impl Lighting { Self { shadow_map_atlas: Self::create_shadow_map_atlas(&light_slab, atlas_size), analytical_lights: Default::default(), - analytical_lights_array: Arc::new(Mutex::new(light_slab.new_array([]))), + analytical_lights_array: Default::default(), geometry_slab: geometry.slab_allocator().clone(), light_slab, light_slab_buffer: Arc::new(RwLock::new(light_slab_buffer)), @@ -306,21 +331,18 @@ impl Lighting { /// This can be used to add the light back to the scene after using /// [`Lighting::remove_light`]. pub fn add_light(&self, bundle: &AnalyticalLightBundle) { - { - // Update the array of light ids - // UNWRAP: POP - let mut analytical_lights_array_guard = self.analytical_lights_array.lock().unwrap(); - let mut analytical_light_ids_vec = analytical_lights_array_guard.get_vec(); - analytical_light_ids_vec.push(bundle.light.id()); - *analytical_lights_array_guard = self.light_slab.new_array(analytical_light_ids_vec); - } - { - // Update our list of weakly ref'd light bundles - self.analytical_lights - .lock() - .unwrap() - .push(AnalyticalLightBundle::::from_hybrid(bundle)); - } + log::trace!( + "adding light {:?} ({})", + bundle.light.id(), + bundle.light_details.style() + ); + // Update our list of weakly ref'd light bundles + self.analytical_lights + .write() + .unwrap() + .push(AnalyticalLightBundle::::from_hybrid(bundle)); + // Invalidate the array of lights + *self.analytical_lights_array.write().unwrap() = None; } /// Remove an [`AnalyticalLightBundle`] from the internal list of lights. @@ -329,15 +351,21 @@ impl Lighting { /// /// After calling this function you can include the light again using [`Lighting::add_light`]. pub fn remove_light(&self, bundle: &AnalyticalLightBundle) { - let ids = { - let mut guard = self.analytical_lights.lock().unwrap(); - guard.retain(|stored_light| stored_light.light.id() != bundle.light.id()); - guard - .iter() - .map(|stored_light| stored_light.light.id()) - .collect::>() - }; - *self.analytical_lights_array.lock().unwrap() = self.light_slab.new_array(ids); + log::trace!( + "removing light {:?} ({})", + bundle.light.id(), + bundle.light_details.style() + ); + // Remove the light from the list of weakly ref'd light bundles + let mut guard = self.analytical_lights.write().unwrap(); + guard.retain(|stored_light| stored_light.light.id() != bundle.light.id()); + *self.analytical_lights_array.write().unwrap() = None; + } + + /// Return an iterator over all lights. + pub fn lights(&self) -> impl Iterator + '_ { + let inner = self.analytical_lights.read().unwrap(); + AnalyticalLightIterator { inner, index: 0 } } /// Create a new [`AnalyticalLightBundle`] for the given descriptor `T`. @@ -369,6 +397,11 @@ impl Lighting { light_details, transform, }; + log::trace!( + "created light {:?} ({})", + bundle.light.id(), + bundle.light_details.style() + ); self.add_light(&bundle); @@ -396,22 +429,49 @@ impl Lighting { #[must_use] pub fn commit(&self) -> SlabBuffer { - { - // Drop any analytical lights that don't have external references, - // and update our lights array. - let mut guard = self.analytical_lights.lock().unwrap(); - let mut changed = false; - guard.retain(|light_bundle| { + log::trace!("committing lights"); + let lights_array = { + let mut lights_guard = self.analytical_lights.write().unwrap(); + // Update the list of analytical lights to only reference lights that are still + // held somewhere in the outside program. + let mut analytical_lights_dropped = false; + lights_guard.retain(|light_bundle| { let has_refs = light_bundle.light.has_external_references(); - changed = changed || !has_refs; + if !has_refs { + log::trace!( + " light {:?} ({}) was dropped", + light_bundle.light.id(), + light_bundle.light_details.style() + ); + } + analytical_lights_dropped = analytical_lights_dropped || !has_refs; has_refs }); - if changed { - *self.analytical_lights_array.lock().unwrap() = self - .light_slab - .new_array(guard.iter().map(|bundle| bundle.light.id())); + + // If lights have been dropped, invalidate the array + let mut array_guard = self.analytical_lights_array.write().unwrap(); + if analytical_lights_dropped { + array_guard.take(); } - } + + // If lights have been invalidated (either by some being dropped or if + // it was previously invalidated by `Lighting::add_light` or `Lighting::remove_light`), + // create a new array + array_guard + .get_or_insert_with(|| { + log::trace!(" analytical lights array was invalidated"); + let new_lights = lights_guard + .iter() + .map(|bundle| bundle.light.id()) + .collect::>(); + log::trace!(" lights are now: {new_lights:?}"); + let array = self.light_slab.new_array(new_lights); + log::trace!(" lights array is now: {array:?}"); + array + }) + .array() + }; + self.lighting_descriptor.modify( |LightingDescriptor { analytical_lights_array, @@ -419,836 +479,18 @@ impl Lighting { update_shadow_map_id, update_shadow_map_texture_index, }| { - *analytical_lights_array = self.analytical_lights_array.lock().unwrap().array(); + *analytical_lights_array = lights_array; *shadow_map_atlas_descriptor_id = self.shadow_map_atlas.descriptor_id(); *update_shadow_map_id = Id::NONE; *update_shadow_map_texture_index = 0; }, ); - self.light_slab.commit() + + let buffer = self.light_slab.commit(); + log::trace!(" light slab creation time: {}", buffer.creation_time()); + buffer } } #[cfg(test)] -mod test { - - use core::time::Duration; - use std::time::Instant; - - use craballoc::runtime::CpuRuntime; - use crabslab::{Array, CpuSlab, Slab}; - use glam::{UVec3, Vec2, Vec3, Vec4, Vec4Swizzles}; - use plotters::{ - chart::{ChartBuilder, SeriesLabelPosition}, - prelude::{ - BitMapBackend, Circle, EmptyElement, IntoDrawingArea, IntoSegmentedCoord, PathElement, - Text, - }, - series::{Histogram, LineSeries, PointSeries}, - style::{Color, IntoFont, ShapeStyle}, - }; - use spirv_std::num_traits::Zero; - - use crate::{ - bvol::BoundingBox, - camera::Camera, - color::linear_xfer_vec4, - draw::DrawIndirectArgs, - geometry::GeometryDescriptor, - light::{ - LightTile, LightTiling, LightTilingDescriptor, LightTilingInvocation, - SpotLightCalculation, - }, - math::{hex_to_vec4, scaled_f32_to_u8, ConstTexture, CpuTexture2d, GpuRng, NonAtomicSlab}, - pbr::Material, - prelude::Transform, - stage::{Renderlet, Stage, Vertex}, - }; - - use super::*; - - #[test] - /// Ensures that a spot light can determine if a point lies inside or outside its cone - /// of emission. - fn spot_one_calc() { - let (doc, _, _) = gltf::import( - crate::test::workspace_dir() - .join("gltf") - .join("spot_one.glb"), - ) - .unwrap(); - let light = doc.lights().unwrap().next().unwrap(); - let spot = if let gltf::khr_lights_punctual::Kind::Spot { - inner_cone_angle, - outer_cone_angle, - } = light.kind() - { - (inner_cone_angle, outer_cone_angle) - } else { - panic!("not a spot light"); - }; - log::info!("spot: {spot:#?}"); - - let light_node = doc.nodes().find(|node| node.light().is_some()).unwrap(); - let parent_transform = Transform::from(light_node.transform()); - log::info!("parent_transform: {parent_transform:#?}"); - - let spot_descriptor = SpotLightDescriptor { - position: Vec3::ZERO, - direction: Vec3::NEG_Z, - inner_cutoff: spot.0, - outer_cutoff: spot.1, - color: Vec3::from(light.color()).extend(1.0), - intensity: light.intensity(), - }; - - let specific_points = [ - (Vec3::ZERO, true, true, Some(1.0)), - (Vec3::new(0.5, 0.0, 0.0), false, true, None), - (Vec3::new(0.5, 0.0, 0.5), false, false, None), - (Vec3::new(1.0, 0.0, 0.0), false, false, Some(0.0)), - ]; - for (i, (point, inside_inner, inside_outer, maybe_contribution)) in - specific_points.into_iter().enumerate() - { - log::info!("{i} descriptor: {spot_descriptor:#?}"); - let spot_calc = - SpotLightCalculation::new(spot_descriptor, parent_transform.into(), point); - log::info!("{i} spot_calc@{point}:\n{spot_calc:#?}"); - assert_eq!( - (inside_inner, inside_outer), - ( - spot_calc.fragment_is_inside_inner_cone, - spot_calc.fragment_is_inside_outer_cone - ), - ); - if let Some(expected_contribution) = maybe_contribution { - assert_eq!(expected_contribution, spot_calc.contribution); - } - } - } - - #[test] - /// Ensures that a spot light illuminates only the objects within its cone of - /// emission. - fn spot_one_frame() { - let m = 32.0; - let (w, h) = (16.0f32 * m, 9.0 * m); - let ctx = crate::Context::headless(w as u32, h as u32); - let stage = ctx.new_stage().with_msaa_sample_count(4); - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("spot_one.glb"), - ) - .unwrap(); - let camera = doc.cameras.first().unwrap(); - camera - .as_ref() - .modify(|cam| cam.set_projection(crate::camera::perspective(w, h))); - stage.use_camera(camera); - - let frame = ctx.get_next_frame().unwrap(); - stage.render(&frame.view()); - let img = frame.read_image().unwrap(); - img_diff::assert_img_eq("light/spot_lights/one.png", img); - frame.present(); - } - - #[test] - /// Test the spot lights. - /// - /// This should render a cube with two spot lights illuminating a spot on two - /// of its sides. - fn spot_lights() { - let w = 800.0; - let h = 800.0; - let ctx = crate::Context::headless(w as u32, h as u32); - let stage = ctx - .new_stage() - .with_lighting(true) - .with_msaa_sample_count(4); - - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("spot_lights.glb"), - ) - .unwrap(); - let camera = doc.cameras.first().unwrap(); - camera - .as_ref() - .modify(|cam| cam.set_projection(crate::camera::perspective(w, h))); - stage.use_camera(camera); - - let down_light = doc.lights.first().unwrap(); - log::info!( - "down_light: {:#?}", - down_light.light_details.as_spot().unwrap().get() - ); - - let frame = ctx.get_next_frame().unwrap(); - stage.render(&frame.view()); - let img = frame.read_image().unwrap(); - img_diff::assert_img_eq("light/spot_lights/frame.png", img); - frame.present(); - } - - #[test] - fn light_tiling_light_bounds() { - let magnification = 8; - let w = 16.0 * 2.0f32.powi(magnification); - let h = 9.0 * 2.0f32.powi(magnification); - let ctx = crate::Context::headless(w as u32, h as u32); - let stage = ctx.new_stage().with_msaa_sample_count(4); - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("light_tiling_test.glb"), - ) - .unwrap(); - let camera = doc.cameras.first().unwrap(); - - stage.use_camera(camera); - - let _lights = crate::test::make_two_directional_light_setup(&stage); - - // Here we only want to render the bounding boxes of the renderlets, - // so mark the renderlets themeselves invisible - doc.renderlets_iter().for_each(|hy_rend| { - hy_rend.modify(|r| { - r.visible = false; - }); - }); - - let colors = [0x6DE1D2FF, 0xFFD63AFF, 0x6DE1D2FF, 0xF75A5AFF].map(|albedo_factor| { - stage.new_material(Material { - albedo_factor: { - let mut color = crate::math::hex_to_vec4(albedo_factor); - linear_xfer_vec4(&mut color); - color - }, - ..Default::default() - }) - }); - let mut resources = vec![]; - for (i, node) in doc.nodes.iter().enumerate() { - if node.mesh.is_none() { - continue; - } - let transform = Mat4::from(node.transform.get_global_transform()); - if let Some(mesh_index) = node.mesh { - log::info!("mesh: {}", node.name.as_deref().unwrap_or("unknown")); - let mesh = &doc.meshes[mesh_index]; - for prim in mesh.primitives.iter() { - let (min, max) = prim.bounding_box; - let min = transform.transform_point3(min); - let max = transform.transform_point3(max); - let bb = BoundingBox::from_min_max(min, max); - if bb.half_extent.min_element().is_zero() { - log::warn!("bounding box is not a volume, skipping"); - continue; - } - log::info!("min: {min}, max: {max}"); - resources.push( - stage - .builder() - .with_vertices({ - bb.get_mesh() - .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)) - }) - .with_material_id(colors[i % colors.len()].id()) - .build(), - ); - } - } - } - - let frame = ctx.get_next_frame().unwrap(); - stage.render(&frame.view()); - let img = frame.read_image().unwrap(); - img_diff::save("light/tiling/bounds.png", img); - frame.present(); - } - - fn gen_vec3(prng: &mut GpuRng) -> Vec3 { - let x = prng.gen_f32(-120.0, 120.0); - let y = prng.gen_f32(0.0, 80.0); - let z = prng.gen_f32(-120.0, 120.0); - Vec3::new(x, y, z) - } - - fn gen_light( - stage: &Stage, - prng: &mut GpuRng, - bounding_boxes: &[BoundingBox], - ) -> ( - Hybrid, - HybridArray, - Hybrid, - AnalyticalLightBundle, - Hybrid, - ) { - let mut position = gen_vec3(prng); - while bounding_boxes.iter().any(|bb| bb.contains_point(position)) { - position = gen_vec3(prng); - } - assert!(!position.x.is_nan()); - assert!(!position.y.is_nan()); - assert!(!position.z.is_nan()); - - let color = Vec4::new( - prng.gen_f32(0.0, 1.0), - prng.gen_f32(0.0, 1.0), - prng.gen_f32(0.0, 1.0), - 1.0, - ); - - let scale = prng.gen_f32(0.1, 1.0); - - let light_bb = BoundingBox { - center: Vec3::ZERO, - half_extent: Vec3::new(scale, scale, scale) * 0.5, - }; - - // Also make a renderlet for the light, so we can see where it is. - let transform = stage.new_nested_transform(); - transform.modify(|t| { - t.translation = position; - }); - let rez = stage - .builder() - .with_transform(Transform { - translation: position, - ..Default::default() - }) - .with_vertices( - light_bb - .get_mesh() - .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)), - ) - .with_material(Material { - albedo_factor: color, - has_lighting: false, - emissive_factor: color.xyz(), - emissive_strength_multiplier: 100.0, - ..Default::default() - }) - .suffix({ - // suffix the actual analytical light - let intensity = scale * 100.0; - - let light_descriptor = PointLightDescriptor { - position, - color, - intensity, - }; - - stage.new_analytical_light(light_descriptor, None) - }) - .build(); - rez - } - - fn size() -> UVec2 { - UVec2::new( - (10.0 * 2.0f32.powi(8)) as u32, - (9.0 * 2.0f32.powi(8)) as u32, - ) - } - - fn make_camera() -> Camera { - let size = size(); - Camera::new( - Mat4::perspective_rh( - std::f32::consts::FRAC_PI_4, - size.x as f32 / size.y as f32, - 50.0, - 600.0, - ), - Mat4::look_at_rh(Vec3::new(250.0, 200.0, 250.0), Vec3::ZERO, Vec3::Y), - ) - } - - #[test] - /// Test the light tiling feature. - fn light_tiling_cpu_sanity() { - let _ = env_logger::builder().is_test(true).try_init(); - let size = size(); - let ctx = crate::Context::headless(size.x, size.y); - let stage = ctx - .new_stage() - .with_lighting(true) - .with_bloom(true) - .with_bloom_mix_strength(0.5); - - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("light_tiling_test.glb"), - ) - .unwrap(); - - let camera = stage.new_camera(make_camera()); - stage.use_camera(camera); - - let moonlight = doc.lights.first().unwrap(); - let _shadow = { - let sm = stage - .new_shadow_map(moonlight, UVec2::splat(1024), 0.1, 256.0) - .unwrap(); - sm.shadowmap_descriptor.modify(|d| { - d.bias_min = 0.0; - d.bias_max = 0.0; - d.pcf_samples = 2; - }); - sm.update(&stage, doc.renderlets_iter()).unwrap(); - sm - }; - - let mut bounding_boxes = vec![]; - for node in doc.nodes.iter() { - if node.mesh.is_none() { - continue; - } - let transform = Mat4::from(node.transform.get_global_transform()); - if let Some(mesh_index) = node.mesh { - let mesh = &doc.meshes[mesh_index]; - for prim in mesh.primitives.iter() { - let (min, max) = prim.bounding_box; - let min = transform.transform_point3(min); - let max = transform.transform_point3(max); - let bb = BoundingBox::from_min_max(min, max); - if bb.half_extent.min_element().is_zero() { - continue; - } - bounding_boxes.push(bb); - } - } - } - - let mut prng = crate::math::GpuRng::new(666); - let mut lights = vec![]; - - for _ in 0..MAX_LIGHTS { - lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); - } - - // Remove the light meshes - for (_, _, _, _, renderlet) in lights.iter() { - stage.remove_renderlet(renderlet); - } - snapshot( - &ctx, - &stage, - "light/tiling/cpu/4-after-lights-no-meshes.png", - ); - - // Get all the slabs and run the shader on the CPU - - let tiling = LightTiling::new(ctx.runtime(), false, size, 32); - let desc = tiling.descriptor().get(); - let depth = stage.depth_texture.read().unwrap(); - let depth_img = crate::texture::read_depth_texture_to_image( - ctx.runtime(), - size.x as usize, - size.y as usize, - &depth.texture, - ) - .unwrap(); - let geometry_slab = - futures_lite::future::block_on(stage.geometry.slab_allocator().read(..)).unwrap(); - let lighting_slab = - futures_lite::future::block_on(stage.lighting.slab_allocator().read(..)).unwrap(); - let tiling_slab = { - tiling.prepare(UVec2::new(depth_img.width(), depth_img.height())); - let _ = tiling.tiling_slab.commit(); - futures_lite::future::block_on(tiling.tiling_slab.read(..)).unwrap() - }; - - let w = depth_img.width() / LightTilingDescriptor::TILE_SIZE.x + 1; - let h = depth_img.height() / LightTilingDescriptor::TILE_SIZE.y + 1; - let mut non_atomic_tiling_slab = NonAtomicSlab::new(tiling_slab); - let depth_img = CpuTexture2d::from_image(depth_img, crate::math::luma_u8_to_vec4); - for x in 0..w { - for y in 0..h { - let global_id = UVec3::new(x, y, 0); - let invocation = LightTilingInvocation::new(global_id, desc); - invocation.compute_tiles( - &depth_img, - &geometry_slab, - &lighting_slab, - &mut non_atomic_tiling_slab, - ); - } - } - } - - #[test] - /// Test the light tiling feature. - fn light_tiling_sanity() { - let _ = env_logger::builder().is_test(true).try_init(); - let size = size(); - let ctx = crate::Context::headless(size.x, size.y); - let stage = ctx - .new_stage() - .with_lighting(false) - .with_bloom(true) - .with_bloom_mix_strength(0.5); - - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("light_tiling_test.glb"), - ) - .unwrap(); - - let camera = stage.new_camera(make_camera()); - stage.use_camera(camera); - snapshot(&ctx, &stage, "light/tiling/1-no-lighting.png"); - - stage.set_has_lighting(true); - - let moonlight = doc.lights.first().unwrap(); - let _shadow = { - let sm = stage - .new_shadow_map(moonlight, UVec2::splat(1024), 0.1, 256.0) - .unwrap(); - sm.shadowmap_descriptor.modify(|d| { - d.bias_min = 0.0; - d.bias_max = 0.0; - d.pcf_samples = 2; - }); - sm.update(&stage, doc.renderlets_iter()).unwrap(); - sm - }; - snapshot(&ctx, &stage, "light/tiling/2-before-lights.png"); - - crate::test::capture_gpu_frame(&ctx, "light/tiling/2.gputrace", || { - let frame = ctx.get_next_frame().unwrap(); - stage.render(&frame.view()); - frame.present(); - }); - - let mut bounding_boxes = vec![]; - for node in doc.nodes.iter() { - if node.mesh.is_none() { - continue; - } - let transform = Mat4::from(node.transform.get_global_transform()); - if let Some(mesh_index) = node.mesh { - let mesh = &doc.meshes[mesh_index]; - for prim in mesh.primitives.iter() { - let (min, max) = prim.bounding_box; - let min = transform.transform_point3(min); - let max = transform.transform_point3(max); - let bb = BoundingBox::from_min_max(min, max); - if bb.half_extent.min_element().is_zero() { - continue; - } - bounding_boxes.push(bb); - } - } - } - log::info!("have {} bounding boxes", bounding_boxes.len()); - - let mut prng = crate::math::GpuRng::new(666); - let mut lights: Vec<( - Hybrid, - HybridArray, - Hybrid, - AnalyticalLightBundle, - Hybrid, - )> = vec![]; - - for _ in 0..MAX_LIGHTS { - lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); - } - snapshot(&ctx, &stage, "light/tiling/3-after-lights.png"); - - // Remove the light meshes - for (_, _, _, _, renderlet) in lights.iter() { - stage.remove_renderlet(renderlet); - } - snapshot(&ctx, &stage, "light/tiling/4-after-lights-no-meshes.png"); - - let tiling = LightTiling::new(ctx.runtime(), false, size, 32); - let desc = tiling.descriptor().get(); - let depth = stage.depth_texture.read().unwrap(); - let mut depth_img = crate::texture::read_depth_texture_f32( - ctx.runtime(), - size.x as usize, - size.y as usize, - depth.texture.as_ref(), - ) - .unwrap(); - // let mut depth_img = crate::texture::read_depth_texture_to_image( - // ctx.runtime(), - // size.x as usize, - // size.y as usize, - // &depth.texture, - // ) - // .unwrap(); - // img_diff::normalize_gray_img(&mut depth_img); - img_diff::save("light/tiling/5-depth.png", depth_img); - tiling.run(&stage.geometry.commit(), &stage.lighting.commit(), &depth); - let (mut mins_img, mut maxs_img, mut lights_img) = - futures_lite::future::block_on(tiling.read_images()); - img_diff::normalize_gray_img(&mut mins_img); - img_diff::normalize_gray_img(&mut maxs_img); - img_diff::normalize_gray_img(&mut lights_img); - img_diff::save("light/tiling/5-mins.png", mins_img); - img_diff::save("light/tiling/5-maxs.png", maxs_img); - img_diff::save("light/tiling/5-lights.png", lights_img); - - return; - log::info!("running stats"); - - // Stats - let mut stats = LightTilingStats::default(); - for number_of_lights in [ - 1, - MAX_LIGHTS / 8, - MAX_LIGHTS / 4, - MAX_LIGHTS / 2, - ((MAX_LIGHTS / 2) + MAX_LIGHTS) / 2, - MAX_LIGHTS, - ] { - let mut run = LightTilingStatsRun { - number_of_lights, - iterations: vec![], - }; - - for (i, (_, _, _, light, _)) in lights.iter().enumerate() { - stage.remove_light(light); - if i < number_of_lights { - stage.add_light(light); - } - } - - const NUM_RUNS: usize = 2; - for i in 0..NUM_RUNS { - log::info!("{number_of_lights} {i} running"); - let start = Instant::now(); - let frame = ctx.get_next_frame().unwrap(); - stage.render(&frame.view()); - frame.present(); - ctx.get_device().poll(wgpu::Maintain::wait()); - let duration = start.elapsed(); - run.iterations.push(duration); - } - stats.runs.push(run); - } - plot(stats); - } - - fn snapshot(ctx: &crate::Context, stage: &Stage, path: &str) { - let frame = ctx.get_next_frame().unwrap(); - let start = std::time::Instant::now(); - stage.render(&frame.view()); - let elapsed = start.elapsed(); - log::info!("shapshot: {}s '{path}'", elapsed.as_secs_f32()); - let img = frame.read_image().unwrap(); - img_diff::save(path, img); - frame.present(); - } - - const MAX_LIGHTS: usize = 1024; - - struct LightTilingStatsRun { - number_of_lights: usize, - iterations: Vec, - } - - impl LightTilingStatsRun { - fn avg_frame_time(&self) -> f32 { - let total: Duration = self.iterations.iter().sum(); - total.as_secs_f32() / self.iterations.len() as f32 - } - } - - #[derive(Default)] - struct LightTilingStats { - runs: Vec, - } - - fn plot(stats: LightTilingStats) { - let path = crate::test::workspace_dir().join("test_output/lights/tiling/frame-time.png"); - let root_drawing_area = BitMapBackend::new(&path, (800, 600)).into_drawing_area(); - root_drawing_area.fill(&plotters::style::WHITE).unwrap(); - - let mut chart = ChartBuilder::on(&root_drawing_area) - .caption( - "Renderling lighting frame time", - ("sans-serif", 50).into_font(), - ) - .margin(30) - .margin_right(100) - .x_label_area_size(30) - .y_label_area_size(30) - .build_cartesian_2d( - 0..MAX_LIGHTS + 1, - 0.0..stats - .runs - .iter() - .map(|r| r.avg_frame_time()) - .max_by(|a, b| a.total_cmp(b)) - .unwrap_or_default(), - ) - .unwrap(); - chart - .configure_mesh() - .x_desc("number of lights") - .y_desc("avg fps") - .draw() - .unwrap(); - - chart - .draw_series(LineSeries::new( - stats - .runs - .iter() - .map(|r| (r.number_of_lights, r.avg_frame_time())), - plotters::style::RED, - )) - .unwrap() - .label("without-tiling") - .legend(|(x, y)| { - PathElement::new(vec![(x, y), (x + 20, y)], plotters::style::RED.filled()) - }); - chart - .draw_series(PointSeries::of_element( - stats - .runs - .iter() - .map(|r| (r.number_of_lights, r.avg_frame_time())), - 5, - ShapeStyle::from(&plotters::style::RED).filled(), - &|(num_lights, seconds_per_frame), size, style| { - EmptyElement::at((num_lights, seconds_per_frame)) - + Circle::new((0, 0), size, style) - + Text::new( - format!("({num_lights}, {:.2} fps)", 1.0 / seconds_per_frame), - (0, 15), - ("sans-serif", 15), - ) - }, - )) - .unwrap(); - - chart - .configure_series_labels() - .position(SeriesLabelPosition::LowerRight) - .margin(20) - .label_font(("sans-serif", 20)) - .draw() - .unwrap(); - root_drawing_area.present().unwrap(); - } - - #[test] - /// Ensures that a point light with a translated position renders the same - /// as a point light at the origin that has a transform applied with - /// that same translation. - /// - /// In other words, light in nested transform is the same as light - fn point_light_transform() { - let ctx = crate::Context::headless(256, 256); - let stage = ctx - .new_stage() - .with_lighting(false) - .with_bloom_mix_strength(0.08); - let doc = stage - .load_gltf_document_from_path( - crate::test::workspace_dir() - .join("gltf") - .join("pedastal.glb"), - ) - .unwrap(); - let camera = doc.cameras.first().unwrap(); - camera.camera.modify(|cam| { - cam.set_projection(Mat4::perspective_rh( - std::f32::consts::FRAC_PI_6, - 1.0, - 0.1, - 15.0, - )); - }); - - let color = { - let mut c = hex_to_vec4(0xEEDF7AFF); - linear_xfer_vec4(&mut c); - c - }; - let position = Vec3::new(0.0, 1.0, 0.0); - let transform = stage.new_nested_transform(); - transform.modify(|t| t.translation = position); - - stage.set_has_lighting(true); - // let _dir_light = stage.new_analytical_light( - // DirectionalLightDescriptor { - // direction: Vec3::NEG_Y, - // color, - // intensity: 1.0, - // }, - // None, - // ); - // snapshot(&ctx, &stage, "light/point/transform-direction.png"); - - let bb = BoundingBox { - center: Vec3::ZERO, - half_extent: Vec3::splat(0.25), - }; - let _light_mesh_rez = stage - .builder() - .with_transform_id(transform.global_transform_id()) - .with_vertices( - bb.get_mesh() - .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)), - ) - .with_material(Material { - albedo_factor: color, - emissive_factor: color.xyz(), - emissive_strength_multiplier: 4.0, - ..Default::default() - }) - .build(); - - let light_descriptor = PointLightDescriptor { - position: Vec3::ZERO, - color, - intensity: 10.0, - }; - let _light = stage.new_analytical_light(light_descriptor, Some(transform)); - snapshot(&ctx, &stage, "light/point/pedastal.png"); - - // light.transform.modify(|t| t.translation = position); - - // snapshot(&ctx, &stage, "light/point/transform-nest.png"); - - // let light_slab = - // futures_lite::future::block_on(stage.lighting.light_slab.read(..)).unwrap(); - // let frag = crate::pbr::shade_fragment( - // &ConstTexture::new(Vec4::ZERO), - // &(), - // camera.node_transform.get_global_transform().translation, - // Vec3::Y, - // Vec3::ZERO, - // Vec3::splat(0.5), - // 0.0, - // 1.0, - // 0.0, - // Vec3::ZERO, - // Vec3::ONE, - // Vec3::ONE, - // Vec2::ONE, - // &light_slab, - // ); - // println!("frag: {frag}"); - } -} +mod test; diff --git a/crates/renderling/src/light/cpu/test.rs b/crates/renderling/src/light/cpu/test.rs new file mode 100644 index 0000000..3b86aac --- /dev/null +++ b/crates/renderling/src/light/cpu/test.rs @@ -0,0 +1,825 @@ +//! Tests of the lighting system. + +use core::time::Duration; +use std::time::Instant; + +use craballoc::runtime::CpuRuntime; +use crabslab::{Array, CpuSlab, Slab}; +use glam::{UVec3, Vec2, Vec3, Vec4, Vec4Swizzles}; +use plotters::{ + chart::{ChartBuilder, SeriesLabelPosition}, + prelude::{ + BitMapBackend, Circle, EmptyElement, IntoDrawingArea, IntoSegmentedCoord, PathElement, Text, + }, + series::{Histogram, LineSeries, PointSeries}, + style::{Color, IntoFont, ShapeStyle}, +}; +use spirv_std::num_traits::Zero; + +use crate::{ + bvol::BoundingBox, + camera::Camera, + color::linear_xfer_vec4, + draw::DrawIndirectArgs, + geometry::GeometryDescriptor, + light::{ + LightTile, LightTiling, LightTilingDescriptor, LightTilingInvocation, SpotLightCalculation, + }, + math::{hex_to_vec4, scaled_f32_to_u8, ConstTexture, CpuTexture2d, GpuRng, NonAtomicSlab}, + pbr::Material, + prelude::Transform, + stage::{Renderlet, Stage, Vertex}, +}; + +use super::*; + +#[test] +/// Ensures that a spot light can determine if a point lies inside or outside its cone +/// of emission. +fn spot_one_calc() { + let (doc, _, _) = gltf::import( + crate::test::workspace_dir() + .join("gltf") + .join("spot_one.glb"), + ) + .unwrap(); + let light = doc.lights().unwrap().next().unwrap(); + let spot = if let gltf::khr_lights_punctual::Kind::Spot { + inner_cone_angle, + outer_cone_angle, + } = light.kind() + { + (inner_cone_angle, outer_cone_angle) + } else { + panic!("not a spot light"); + }; + log::info!("spot: {spot:#?}"); + + let light_node = doc.nodes().find(|node| node.light().is_some()).unwrap(); + let parent_transform = Transform::from(light_node.transform()); + log::info!("parent_transform: {parent_transform:#?}"); + + let spot_descriptor = SpotLightDescriptor { + position: Vec3::ZERO, + direction: Vec3::NEG_Z, + inner_cutoff: spot.0, + outer_cutoff: spot.1, + color: Vec3::from(light.color()).extend(1.0), + intensity: light.intensity(), + }; + + let specific_points = [ + (Vec3::ZERO, true, true, Some(1.0)), + (Vec3::new(0.5, 0.0, 0.0), false, true, None), + (Vec3::new(0.5, 0.0, 0.5), false, false, None), + (Vec3::new(1.0, 0.0, 0.0), false, false, Some(0.0)), + ]; + for (i, (point, inside_inner, inside_outer, maybe_contribution)) in + specific_points.into_iter().enumerate() + { + log::info!("{i} descriptor: {spot_descriptor:#?}"); + let spot_calc = SpotLightCalculation::new(spot_descriptor, parent_transform.into(), point); + log::info!("{i} spot_calc@{point}:\n{spot_calc:#?}"); + assert_eq!( + (inside_inner, inside_outer), + ( + spot_calc.fragment_is_inside_inner_cone, + spot_calc.fragment_is_inside_outer_cone + ), + ); + if let Some(expected_contribution) = maybe_contribution { + assert_eq!(expected_contribution, spot_calc.contribution); + } + } +} + +#[test] +/// Ensures that a spot light illuminates only the objects within its cone of +/// emission. +fn spot_one_frame() { + let m = 32.0; + let (w, h) = (16.0f32 * m, 9.0 * m); + let ctx = crate::Context::headless(w as u32, h as u32); + let stage = ctx.new_stage().with_msaa_sample_count(4); + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("spot_one.glb"), + ) + .unwrap(); + let camera = doc.cameras.first().unwrap(); + camera + .as_ref() + .modify(|cam| cam.set_projection(crate::camera::perspective(w, h))); + stage.use_camera(camera); + + let frame = ctx.get_next_frame().unwrap(); + stage.render(&frame.view()); + let img = frame.read_image().unwrap(); + img_diff::assert_img_eq("light/spot_lights/one.png", img); + frame.present(); +} + +#[test] +/// Test the spot lights. +/// +/// This should render a cube with two spot lights illuminating a spot on two +/// of its sides. +fn spot_lights() { + let w = 800.0; + let h = 800.0; + let ctx = crate::Context::headless(w as u32, h as u32); + let stage = ctx + .new_stage() + .with_lighting(true) + .with_msaa_sample_count(4); + + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("spot_lights.glb"), + ) + .unwrap(); + let camera = doc.cameras.first().unwrap(); + camera + .as_ref() + .modify(|cam| cam.set_projection(crate::camera::perspective(w, h))); + stage.use_camera(camera); + + let down_light = doc.lights.first().unwrap(); + log::info!( + "down_light: {:#?}", + down_light.light_details.as_spot().unwrap().get() + ); + + let frame = ctx.get_next_frame().unwrap(); + stage.render(&frame.view()); + let img = frame.read_image().unwrap(); + img_diff::assert_img_eq("light/spot_lights/frame.png", img); + frame.present(); +} + +#[test] +fn light_tiling_light_bounds() { + let magnification = 8; + let w = 16.0 * 2.0f32.powi(magnification); + let h = 9.0 * 2.0f32.powi(magnification); + let ctx = crate::Context::headless(w as u32, h as u32); + let stage = ctx.new_stage().with_msaa_sample_count(4); + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("light_tiling_test.glb"), + ) + .unwrap(); + let camera = doc.cameras.first().unwrap(); + + stage.use_camera(camera); + + let _lights = crate::test::make_two_directional_light_setup(&stage); + + // Here we only want to render the bounding boxes of the renderlets, + // so mark the renderlets themeselves invisible + doc.renderlets_iter().for_each(|hy_rend| { + hy_rend.modify(|r| { + r.visible = false; + }); + }); + + let colors = [0x6DE1D2FF, 0xFFD63AFF, 0x6DE1D2FF, 0xF75A5AFF].map(|albedo_factor| { + stage.new_material(Material { + albedo_factor: { + let mut color = crate::math::hex_to_vec4(albedo_factor); + linear_xfer_vec4(&mut color); + color + }, + ..Default::default() + }) + }); + let mut resources = vec![]; + for (i, node) in doc.nodes.iter().enumerate() { + if node.mesh.is_none() { + continue; + } + let transform = Mat4::from(node.transform.get_global_transform()); + if let Some(mesh_index) = node.mesh { + log::info!("mesh: {}", node.name.as_deref().unwrap_or("unknown")); + let mesh = &doc.meshes[mesh_index]; + for prim in mesh.primitives.iter() { + let (min, max) = prim.bounding_box; + let min = transform.transform_point3(min); + let max = transform.transform_point3(max); + let bb = BoundingBox::from_min_max(min, max); + if bb.half_extent.min_element().is_zero() { + log::warn!("bounding box is not a volume, skipping"); + continue; + } + log::info!("min: {min}, max: {max}"); + resources.push( + stage + .builder() + .with_vertices({ + bb.get_mesh() + .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)) + }) + .with_material_id(colors[i % colors.len()].id()) + .build(), + ); + } + } + } + + let frame = ctx.get_next_frame().unwrap(); + stage.render(&frame.view()); + let img = frame.read_image().unwrap(); + img_diff::save("light/tiling/bounds.png", img); + frame.present(); +} + +fn gen_vec3(prng: &mut GpuRng) -> Vec3 { + let x = prng.gen_f32(-120.0, 120.0); + let y = prng.gen_f32(0.0, 80.0); + let z = prng.gen_f32(-120.0, 120.0); + Vec3::new(x, y, z) +} + +fn gen_light( + stage: &Stage, + prng: &mut GpuRng, + bounding_boxes: &[BoundingBox], +) -> ( + Hybrid, + HybridArray, + Hybrid, + AnalyticalLightBundle, + Hybrid, +) { + let mut position = gen_vec3(prng); + while bounding_boxes.iter().any(|bb| bb.contains_point(position)) { + position = gen_vec3(prng); + } + assert!(!position.x.is_nan()); + assert!(!position.y.is_nan()); + assert!(!position.z.is_nan()); + + let color = Vec4::new( + prng.gen_f32(0.0, 1.0), + prng.gen_f32(0.0, 1.0), + prng.gen_f32(0.0, 1.0), + 1.0, + ); + + let scale = prng.gen_f32(0.1, 1.0); + + let light_bb = BoundingBox { + center: Vec3::ZERO, + half_extent: Vec3::new(scale, scale, scale) * 0.5, + }; + + // Also make a renderlet for the light, so we can see where it is. + let transform = stage.new_nested_transform(); + transform.modify(|t| { + t.translation = position; + }); + let rez = stage + .builder() + .with_transform(Transform { + translation: position, + ..Default::default() + }) + .with_vertices( + light_bb + .get_mesh() + .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)), + ) + .with_material(Material { + albedo_factor: color, + has_lighting: false, + emissive_factor: color.xyz(), + emissive_strength_multiplier: 100.0, + ..Default::default() + }) + .suffix({ + // suffix the actual analytical light + let intensity = scale * 100.0; + + let light_descriptor = PointLightDescriptor { + position, + color, + intensity, + }; + + stage.new_analytical_light(light_descriptor, None) + }) + .build(); + rez +} + +fn size() -> UVec2 { + UVec2::new( + (10.0 * 2.0f32.powi(8)) as u32, + (9.0 * 2.0f32.powi(8)) as u32, + ) +} + +fn make_camera() -> Camera { + let size = size(); + Camera::new( + Mat4::perspective_rh( + std::f32::consts::FRAC_PI_4, + size.x as f32 / size.y as f32, + 50.0, + 600.0, + ), + Mat4::look_at_rh(Vec3::new(250.0, 200.0, 250.0), Vec3::ZERO, Vec3::Y), + ) +} + +#[test] +/// Test the light tiling feature. +fn light_tiling_cpu_sanity() { + let _ = env_logger::builder().is_test(true).try_init(); + let size = size(); + let ctx = crate::Context::headless(size.x, size.y); + let stage = ctx + .new_stage() + .with_lighting(true) + .with_bloom(true) + .with_bloom_mix_strength(0.5); + + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("light_tiling_test.glb"), + ) + .unwrap(); + + let camera = stage.new_camera(make_camera()); + stage.use_camera(camera); + + let moonlight = doc.lights.first().unwrap(); + let _shadow = { + let sm = stage + .new_shadow_map(moonlight, UVec2::splat(1024), 0.1, 256.0) + .unwrap(); + sm.shadowmap_descriptor.modify(|d| { + d.bias_min = 0.0; + d.bias_max = 0.0; + d.pcf_samples = 2; + }); + sm.update(&stage, doc.renderlets_iter()).unwrap(); + sm + }; + + let mut bounding_boxes = vec![]; + for node in doc.nodes.iter() { + if node.mesh.is_none() { + continue; + } + let transform = Mat4::from(node.transform.get_global_transform()); + if let Some(mesh_index) = node.mesh { + let mesh = &doc.meshes[mesh_index]; + for prim in mesh.primitives.iter() { + let (min, max) = prim.bounding_box; + let min = transform.transform_point3(min); + let max = transform.transform_point3(max); + let bb = BoundingBox::from_min_max(min, max); + if bb.half_extent.min_element().is_zero() { + continue; + } + bounding_boxes.push(bb); + } + } + } + + let mut prng = crate::math::GpuRng::new(666); + let mut lights = vec![]; + + for _ in 0..MAX_LIGHTS { + lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); + } + + // Remove the light meshes + for (_, _, _, _, renderlet) in lights.iter() { + stage.remove_renderlet(renderlet); + } + snapshot( + &ctx, + &stage, + "light/tiling/cpu/4-after-lights-no-meshes.png", + ); + + // Get all the slabs and run the shader on the CPU + let tiling = LightTiling::new(ctx.runtime(), false, size, 32); + let desc = tiling.tiling_descriptor.get(); + let depth = stage.depth_texture.read().unwrap(); + let depth_img = crate::texture::read_depth_texture_to_image( + ctx.runtime(), + size.x as usize, + size.y as usize, + &depth.texture, + ) + .unwrap(); + let geometry_slab = + futures_lite::future::block_on(stage.geometry.slab_allocator().read(..)).unwrap(); + let lighting_slab = + futures_lite::future::block_on(stage.lighting.slab_allocator().read(..)).unwrap(); + let tiling_slab = { + tiling.prepare(UVec2::new(depth_img.width(), depth_img.height())); + let _ = tiling.tiling_slab.commit(); + futures_lite::future::block_on(tiling.tiling_slab.read(..)).unwrap() + }; + + let w = depth_img.width() / LightTilingDescriptor::TILE_SIZE.x + 1; + let h = depth_img.height() / LightTilingDescriptor::TILE_SIZE.y + 1; + let mut non_atomic_tiling_slab = NonAtomicSlab::new(tiling_slab); + let depth_img = CpuTexture2d::from_image(depth_img, crate::math::luma_u8_to_vec4); + for x in 0..w { + for y in 0..h { + let global_id = UVec3::new(x, y, 0); + let invocation = LightTilingInvocation::new(global_id, desc); + invocation.compute_tiles( + &depth_img, + &geometry_slab, + &lighting_slab, + &mut non_atomic_tiling_slab, + ); + } + } +} + +#[test] +/// Test the light tiling feature. +fn light_tiling_sanity() { + let _ = env_logger::builder().is_test(true).try_init(); + let size = size(); + let ctx = crate::Context::headless(size.x, size.y); + let stage = ctx + .new_stage() + .with_lighting(false) + .with_bloom(true) + .with_bloom_mix_strength(0.5); + + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("light_tiling_test.glb"), + ) + .unwrap(); + + let camera = stage.new_camera(make_camera()); + stage.use_camera(camera); + snapshot(&ctx, &stage, "light/tiling/1-no-lighting.png"); + + stage.set_has_lighting(true); + + let moonlight = doc.lights.first().unwrap(); + let _shadow = { + let sm = stage + .new_shadow_map(moonlight, UVec2::splat(1024), 0.1, 256.0) + .unwrap(); + sm.shadowmap_descriptor.modify(|d| { + d.bias_min = 0.0; + d.bias_max = 0.0; + d.pcf_samples = 2; + }); + sm.update(&stage, doc.renderlets_iter()).unwrap(); + sm + }; + snapshot(&ctx, &stage, "light/tiling/2-before-lights.png"); + + crate::test::capture_gpu_frame(&ctx, "light/tiling/2.gputrace", || { + let frame = ctx.get_next_frame().unwrap(); + stage.render(&frame.view()); + frame.present(); + }); + + let mut bounding_boxes = vec![]; + for node in doc.nodes.iter() { + if node.mesh.is_none() { + continue; + } + let transform = Mat4::from(node.transform.get_global_transform()); + if let Some(mesh_index) = node.mesh { + let mesh = &doc.meshes[mesh_index]; + for prim in mesh.primitives.iter() { + let (min, max) = prim.bounding_box; + let min = transform.transform_point3(min); + let max = transform.transform_point3(max); + let bb = BoundingBox::from_min_max(min, max); + if bb.half_extent.min_element().is_zero() { + continue; + } + bounding_boxes.push(bb); + } + } + } + log::info!("have {} bounding boxes", bounding_boxes.len()); + + let mut prng = crate::math::GpuRng::new(666); + let mut lights: Vec<( + Hybrid, + HybridArray, + Hybrid, + AnalyticalLightBundle, + Hybrid, + )> = vec![]; + + for _ in 0..MAX_LIGHTS { + lights.push(gen_light(&stage, &mut prng, &bounding_boxes)); + } + snapshot(&ctx, &stage, "light/tiling/3-after-lights.png"); + + // Remove the light meshes + for (_, _, _, _, renderlet) in lights.iter() { + stage.remove_renderlet(renderlet); + } + snapshot(&ctx, &stage, "light/tiling/4-after-lights-no-meshes.png"); + + let tiling = LightTiling::new(ctx.runtime(), false, size, 32); + let desc = tiling.tiling_descriptor.get(); + let depth = stage.depth_texture.read().unwrap(); + let mut depth_img = crate::texture::read_depth_texture_f32( + ctx.runtime(), + size.x as usize, + size.y as usize, + depth.texture.as_ref(), + ) + .unwrap(); + // let mut depth_img = crate::texture::read_depth_texture_to_image( + // ctx.runtime(), + // size.x as usize, + // size.y as usize, + // &depth.texture, + // ) + // .unwrap(); + // img_diff::normalize_gray_img(&mut depth_img); + img_diff::save("light/tiling/5-depth.png", depth_img); + tiling.run(&stage.geometry.commit(), &stage.lighting.commit(), &depth); + let (mut mins_img, mut maxs_img, mut lights_img) = + futures_lite::future::block_on(tiling.read_images()); + img_diff::normalize_gray_img(&mut mins_img); + img_diff::normalize_gray_img(&mut maxs_img); + img_diff::normalize_gray_img(&mut lights_img); + img_diff::save("light/tiling/5-mins.png", mins_img); + img_diff::save("light/tiling/5-maxs.png", maxs_img); + img_diff::save("light/tiling/5-lights.png", lights_img); + + return; + log::info!("running stats"); + + // Stats + let mut stats = LightTilingStats::default(); + for number_of_lights in [ + 1, + MAX_LIGHTS / 8, + MAX_LIGHTS / 4, + MAX_LIGHTS / 2, + ((MAX_LIGHTS / 2) + MAX_LIGHTS) / 2, + MAX_LIGHTS, + ] { + let mut run = LightTilingStatsRun { + number_of_lights, + iterations: vec![], + }; + + for (i, (_, _, _, light, _)) in lights.iter().enumerate() { + stage.remove_light(light); + if i < number_of_lights { + stage.add_light(light); + } + } + + const NUM_RUNS: usize = 2; + for i in 0..NUM_RUNS { + log::info!("{number_of_lights} {i} running"); + let start = Instant::now(); + let frame = ctx.get_next_frame().unwrap(); + stage.render(&frame.view()); + frame.present(); + ctx.get_device().poll(wgpu::Maintain::wait()); + let duration = start.elapsed(); + run.iterations.push(duration); + } + stats.runs.push(run); + } + plot(stats); +} + +fn snapshot(ctx: &crate::Context, stage: &Stage, path: &str) { + let frame = ctx.get_next_frame().unwrap(); + let start = std::time::Instant::now(); + stage.render(&frame.view()); + let elapsed = start.elapsed(); + log::info!("shapshot: {}s '{path}'", elapsed.as_secs_f32()); + let img = frame.read_image().unwrap(); + img_diff::save(path, img); + frame.present(); +} + +const MAX_LIGHTS: usize = 1024; + +struct LightTilingStatsRun { + number_of_lights: usize, + iterations: Vec, +} + +impl LightTilingStatsRun { + fn avg_frame_time(&self) -> f32 { + let total: Duration = self.iterations.iter().sum(); + total.as_secs_f32() / self.iterations.len() as f32 + } +} + +#[derive(Default)] +struct LightTilingStats { + runs: Vec, +} + +fn plot(stats: LightTilingStats) { + let path = crate::test::workspace_dir().join("test_output/lights/tiling/frame-time.png"); + let root_drawing_area = BitMapBackend::new(&path, (800, 600)).into_drawing_area(); + root_drawing_area.fill(&plotters::style::WHITE).unwrap(); + + let mut chart = ChartBuilder::on(&root_drawing_area) + .caption( + "Renderling lighting frame time", + ("sans-serif", 50).into_font(), + ) + .margin(30) + .margin_right(100) + .x_label_area_size(30) + .y_label_area_size(30) + .build_cartesian_2d( + 0..MAX_LIGHTS + 1, + 0.0..stats + .runs + .iter() + .map(|r| r.avg_frame_time()) + .max_by(|a, b| a.total_cmp(b)) + .unwrap_or_default(), + ) + .unwrap(); + chart + .configure_mesh() + .x_desc("number of lights") + .y_desc("avg fps") + .draw() + .unwrap(); + + chart + .draw_series(LineSeries::new( + stats + .runs + .iter() + .map(|r| (r.number_of_lights, r.avg_frame_time())), + plotters::style::RED, + )) + .unwrap() + .label("without-tiling") + .legend(|(x, y)| { + PathElement::new(vec![(x, y), (x + 20, y)], plotters::style::RED.filled()) + }); + chart + .draw_series(PointSeries::of_element( + stats + .runs + .iter() + .map(|r| (r.number_of_lights, r.avg_frame_time())), + 5, + ShapeStyle::from(&plotters::style::RED).filled(), + &|(num_lights, seconds_per_frame), size, style| { + EmptyElement::at((num_lights, seconds_per_frame)) + + Circle::new((0, 0), size, style) + + Text::new( + format!("({num_lights}, {:.2} fps)", 1.0 / seconds_per_frame), + (0, 15), + ("sans-serif", 15), + ) + }, + )) + .unwrap(); + + chart + .configure_series_labels() + .position(SeriesLabelPosition::LowerRight) + .margin(20) + .label_font(("sans-serif", 20)) + .draw() + .unwrap(); + root_drawing_area.present().unwrap(); +} + +#[test] +/// Ensures that a light with a translated position renders the same +/// as a light at the origin that has a transform applied with +/// that same translation. +/// +/// In other words, light in nested transform is the same as light with +/// that same transform pre-applied. +fn pedestal() { + let ctx = crate::Context::headless(256, 256); + let stage = ctx + .new_stage() + .with_lighting(false) + .with_msaa_sample_count(4) + .with_bloom_mix_strength(0.08); + let doc = stage + .load_gltf_document_from_path( + crate::test::workspace_dir() + .join("gltf") + .join("pedestal.glb"), + ) + .unwrap(); + let camera = doc.cameras.first().unwrap(); + camera.camera.modify(|cam| { + cam.set_projection(Mat4::perspective_rh( + std::f32::consts::FRAC_PI_6, + 1.0, + 0.1, + 15.0, + )); + }); + + let color = { + let mut c = hex_to_vec4(0xEEDF7AFF); + linear_xfer_vec4(&mut c); + c + }; + let position = Vec3::new(0.0, 1.0, 0.0); + let transform = stage.new_nested_transform(); + transform.modify(|t| t.translation = position); + + stage.set_has_lighting(true); + + { + log::info!("adding dir light"); + let _dir_light = stage.new_analytical_light( + DirectionalLightDescriptor { + direction: Vec3::new(-0.5, -1.0, 0.0), + color, + intensity: 5.0, + }, + None, + ); + snapshot(&ctx, &stage, "light/pedestal/directional.png"); + log::info!("dropping dir light"); + } + assert_eq!(0, stage.lighting.lights().count()); + + let bb = BoundingBox { + center: Vec3::ZERO, + half_extent: Vec3::splat(0.25), + }; + let _light_mesh_rez = stage + .builder() + .with_transform_id(transform.global_transform_id()) + .with_vertices( + bb.get_mesh() + .map(|(p, n)| Vertex::default().with_position(p).with_normal(n)), + ) + .with_material(Material { + albedo_factor: color, + emissive_factor: color.xyz(), + emissive_strength_multiplier: 4.0, + ..Default::default() + }) + .build(); + + let light_descriptor = PointLightDescriptor { + position: Vec3::ZERO, + color, + intensity: 10.0, + }; + let _light = stage.new_analytical_light(light_descriptor, Some(transform)); + snapshot(&ctx, &stage, "light/pedestal/point.png"); + + // light.transform.modify(|t| t.translation = position); + + // snapshot(&ctx, &stage, "light/point/transform-nest.png"); + + // let light_slab = + // futures_lite::future::block_on(stage.lighting.light_slab.read(..)).unwrap(); + // let frag = crate::pbr::shade_fragment( + // &ConstTexture::new(Vec4::ZERO), + // &(), + // camera.node_transform.get_global_transform().translation, + // Vec3::Y, + // Vec3::ZERO, + // Vec3::splat(0.5), + // 0.0, + // 1.0, + // 0.0, + // Vec3::ZERO, + // Vec3::ONE, + // Vec3::ONE, + // Vec2::ONE, + // &light_slab, + // ); + // println!("frag: {frag}"); +} diff --git a/crates/renderling/src/light/tiling.rs b/crates/renderling/src/light/tiling.rs index 9a9c571..591be70 100644 --- a/crates/renderling/src/light/tiling.rs +++ b/crates/renderling/src/light/tiling.rs @@ -22,7 +22,7 @@ use super::{LightTile, LightTilingDescriptor}; pub struct LightTiling { // depth_pre_pass_pipeline: Arc, pub(crate) tiling_slab: SlabAllocator, - tiling_descriptor: Hybrid, + pub(crate) tiling_descriptor: Hybrid, _tiles: GpuArray, bind_group_creation_time: Arc, depth_texture_id: Arc, @@ -112,10 +112,6 @@ impl LightTiling { (compute_tiles_pipeline, pipeline_layout, bind_group_layout) } - pub(crate) fn descriptor(&self) -> &Hybrid { - &self.tiling_descriptor - } - pub fn new( runtime: impl AsRef, multisampled: bool, diff --git a/crates/renderling/src/stage/cpu.rs b/crates/renderling/src/stage/cpu.rs index 541f216..8c441bb 100644 --- a/crates/renderling/src/stage/cpu.rs +++ b/crates/renderling/src/stage/cpu.rs @@ -96,6 +96,30 @@ impl StageCommitResult { .max() .unwrap_or_default() } + + pub fn should_invalidate(&self, previous_creation_time: usize) -> bool { + let mut should = false; + if self.geometry_buffer.is_new_this_commit() { + log::trace!("geometry buffer is new this frame"); + should = true; + } + if self.materials_buffer.is_new_this_commit() { + log::trace!("materials buffer is new this frame"); + should = true; + } + if self.lighting_buffer.is_new_this_commit() { + log::trace!("lighting buffer is new this frame"); + should = true; + } + let current = self.latest_creation_time(); + if current > previous_creation_time { + log::trace!( + "current latest buffer creation time {current} > previous {previous_creation_time}" + ); + should = true; + } + should + } } struct RenderletBindGroup<'a> { @@ -200,12 +224,13 @@ impl StageRendering<'_> { current_renderlet_bind_group_creation_time, std::sync::atomic::Ordering::Relaxed, ); - let should_invalidate_renderlet_bind_group = current_renderlet_bind_group_creation_time - > previous_renderlet_bind_group_creation_time; + let should_invalidate_renderlet_bind_group = + commit_result.should_invalidate(previous_renderlet_bind_group_creation_time); let renderlet_bind_group = self.stage .renderlet_bind_group .get(should_invalidate_renderlet_bind_group, || { + log::trace!("recreating renderlet bind group"); let atlas_texture = self.stage.materials.atlas().get_texture(); let skybox = self.stage.skybox.read().unwrap(); let shadow_map = self.stage.lighting.shadow_map_atlas.get_texture();