Skip to content

feature: light tiling #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b20044d
depth pre-pass vertex
schell Mar 22, 2025
2112c8b
gen shaders
schell Mar 22, 2025
a5237f4
light tiling min max depth
schell Mar 24, 2025
8ead2b4
bump spirv-std, use PCG PRNG
schell Apr 18, 2025
6e3655e
remove todo
schell Apr 23, 2025
f949048
bump craballoc
schell Apr 24, 2025
09d289f
feat: implement BoundingBox::get_mesh to return triangle mesh with no…
schell Apr 24, 2025
9083691
added BoundingBox::get_mush
schell Apr 24, 2025
acdcd6c
feat: implement point containment check in BoundingBox struct
schell Apr 24, 2025
6b8fa8d
fix: compare delta against absolute half-extents in contains_point me…
schell Apr 24, 2025
e73e13d
Context has configurable direct draw
schell Apr 25, 2025
e77589a
WIP
schell Apr 26, 2025
eb1233a
WIP - LightTilingDescriptor
schell Apr 27, 2025
729b19c
tiling - can compute min/max tile depth
schell Apr 27, 2025
ad2c162
WIP - light tiling - compute lists
schell Apr 27, 2025
1e06259
WIP - write lights
schell Apr 28, 2025
8f69018
feat: add extents method and intersects_aabb function to Aabb struct
schell Apr 28, 2025
754d1e6
feat: implement Aabb intersection check for axis-aligned bounding boxes
schell Apr 28, 2025
5abba1e
WIP - verify writing lights
schell Apr 30, 2025
e70e1f0
clean up linkage file
schell Apr 30, 2025
8202195
clean up linkage
schell Apr 30, 2025
105700f
WIP
schell May 10, 2025
9ff0b76
pedastal scene
schell May 10, 2025
82085bc
rename pedestal asset
schell May 17, 2025
8730f76
fixed renderlet bindgroup invalidation bug, moved lighting tests to t…
schell May 17, 2025
f35d26f
checkpoint
schell Jul 3, 2025
d2feef2
bump dependencies
schell Jul 6, 2025
5348828
bump crabslab
schell Jul 6, 2025
818efbf
regen shaders, add point light to pedestal test
schell Jul 9, 2025
a9defe1
fix point light frag_to_light direction
schell Jul 10, 2025
d0a029e
reference to blog
schell Jul 10, 2025
41b9a17
read light transforms off the lighting slab instead of the geometry slab
schell Jul 12, 2025
6aa8269
fix: analytical light transform is hosted in the light slab
schell Jul 13, 2025
eebaf1e
added orthonormal_vectors fn to IsVector, updated light's shadow_mapp…
schell Jul 13, 2025
822d7f9
AnalyticalLight holds linked transform in a lock
schell Jul 14, 2025
250d3fa
added math::convert_pixel_depth_into_world_coords and test
schell Jul 19, 2025
a76fd03
camera forward vector and near/far points
schell Jul 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,358 changes: 969 additions & 389 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ exclude = ["./shaders"]
resolver = "2"

[workspace.dependencies]
acorn_prng = "3.0"
assert_approx_eq = "1.1.0"
async-channel = "1.8"
bytemuck = { version = "1.19.0", features = ["derive"] }
cfg_aliases = "0.2"
clap = { version = "4.5.23", features = ["derive"] }
craballoc = { version = "0.1.11" }
crabslab = { version = "0.6.3", default-features = false }
craballoc = { version = "0.2.0" }
crabslab = { version = "0.6.5", default-features = false }
plotters = "0.3.7"
ctor = "0.2.2"
dagga = "0.2.1"
env_logger = "0.10.0"
futures-lite = "1.13"
glam = { version = "0.29", default-features = false }
glam = { version = "0.30", default-features = false }
gltf = { version = "1.4,1", features = ["KHR_lights_punctual", "KHR_materials_unlit", "KHR_materials_emissive_strength", "extras", "extensions"] }
image = "0.25"
log = "0.4"
Expand All @@ -40,8 +40,10 @@ rustc-hash = "1.1"
serde = {version = "1.0", features = ["derive"]}
serde_json = "1.0.117"
send_wrapper = "0.6.0"
similarity = "0.2.0"
snafu = "0.8"
spirv-std = { git = "https://github.com/Rust-GPU/rust-gpu", rev = "6e2c84d" }
spirv-std = { git = "https://github.com/LegNeato/rust-gpu.git", rev = "425328a" }
spirv-std-macros = { git = "https://github.com/LegNeato/rust-gpu.git", rev = "425328a" }
syn = { version = "2.0.49", features = ["full", "extra-traits", "parsing"] }
tracing = "0.1.41"
wasm-bindgen = "0.2"
Expand All @@ -62,4 +64,4 @@ opt-level = 3
opt-level = 3

[patch.crates-io]
spirv-std = { git = "https://github.com/Rust-GPU/rust-gpu", rev = "6e2c84d" }
spirv-std = { git = "https://github.com/LegNeato/rust-gpu.git", rev = "425328a" }
Binary file added blender/normal_mapping_brick_sphere.blend
Binary file not shown.
Binary file added blender/pedestal.blend
Binary file not shown.
28 changes: 11 additions & 17 deletions crates/example-culling/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct CullingExample {
app_camera: AppCamera,
controller: example::camera::TurntableCameraController,
stage: Stage,
dlights: [AnalyticalLightBundle; 2],
dlights: [AnalyticalLight; 2],
material_aabb_overlapping: Hybrid<Material>,
material_aabb_outside: Hybrid<Material>,
material_frustum: Hybrid<Material>,
Expand Down Expand Up @@ -183,22 +183,16 @@ impl TestAppHandler for CullingExample {
let mut seed = 46;
let mut resources = BagOfResources::default();
let stage = ctx.new_stage().with_lighting(true);
let sunlight_a = stage.new_analytical_light(
DirectionalLightDescriptor {
direction: Vec3::new(-0.8, -1.0, 0.5).normalize(),
color: Vec4::ONE,
intensity: 10.0,
},
None,
);
let sunlight_b = stage.new_analytical_light(
DirectionalLightDescriptor {
direction: Vec3::new(1.0, 1.0, -0.1).normalize(),
color: Vec4::ONE,
intensity: 1.0,
},
None,
);
let sunlight_a = stage.new_analytical_light(DirectionalLightDescriptor {
direction: Vec3::new(-0.8, -1.0, 0.5).normalize(),
color: Vec4::ONE,
intensity: 10.0,
});
let sunlight_b = stage.new_analytical_light(DirectionalLightDescriptor {
direction: Vec3::new(1.0, 1.0, -0.1).normalize(),
color: Vec4::ONE,
intensity: 1.0,
});

let dlights = [sunlight_a, sunlight_b];

Expand Down
6 changes: 3 additions & 3 deletions crates/example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use renderling::{
atlas::AtlasImage,
bvol::{Aabb, BoundingSphere},
camera::Camera,
light::{AnalyticalLightBundle, DirectionalLightDescriptor},
light::{AnalyticalLight, DirectionalLightDescriptor},
math::{Mat4, UVec2, Vec2, Vec3, Vec4},
skybox::Skybox,
stage::{Animator, GltfDocument, Renderlet, Stage, Vertex},
Expand Down Expand Up @@ -128,7 +128,7 @@ pub struct App {
loads: Arc<Mutex<HashMap<std::path::PathBuf, Vec<u8>>>>,
pub stage: Stage,
camera: Hybrid<Camera>,
lighting: AnalyticalLightBundle,
lighting: AnalyticalLight,
model: Model,
animators: Option<Vec<Animator>>,
animations_conflict: bool,
Expand All @@ -150,7 +150,7 @@ impl App {
color: renderling::math::hex_to_vec4(0xFDFBD3FF),
intensity: 10.0,
};
let sunlight_bundle = stage.new_analytical_light(directional_light, None);
let sunlight_bundle = stage.new_analytical_light(directional_light);

stage
.set_atlas_size(wgpu::Extent3d {
Expand Down
12 changes: 8 additions & 4 deletions crates/img-diff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ fn checkerboard_background_color(x: u32, y: u32) -> Vec3 {

#[derive(Debug, Snafu)]
enum ImgDiffError {
#[snafu(display("Images are different sizes"))]
ImageSize,
#[snafu(display("Images are different sizes. Expected {lhs:?}, saw {rhs:?}"))]
ImageSize { lhs: (u32, u32), rhs: (u32, u32) },
}

pub struct DiffCfg {
Expand Down Expand Up @@ -68,7 +68,7 @@ fn get_results(
) -> Result<Option<DiffResults>, ImgDiffError> {
let lid @ (width, height) = left_image.dimensions();
let rid = right_image.dimensions();
snafu::ensure!(lid == rid, ImageSizeSnafu);
snafu::ensure!(lid == rid, ImageSizeSnafu { lhs: lid, rhs: rid });

let results = left_image
.enumerate_pixels()
Expand Down Expand Up @@ -147,13 +147,17 @@ pub fn assert_eq_cfg(
image_threshold,
test_name,
} = cfg;
let results = match get_results(&lhs, &rhs, pixel_threshold) {
Ok(maybe_diff) => maybe_diff,
Err(e) => panic!("Asserting {filename} failed: {e}"),
};
if let Some(DiffResults {
num_pixels: diffs,
diff_image,
mask_image,
max_delta_length,
avg_delta_length,
}) = get_results(&lhs, &rhs, pixel_threshold).unwrap()
}) = results
{
println!("{filename} has {diffs} pixel differences (threshold={pixel_threshold})");
println!(" max_delta_length: {max_delta_length}");
Expand Down
42 changes: 31 additions & 11 deletions crates/renderling-build/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#![allow(unexpected_cfgs)]
use naga::{
back::wgsl::WriterFlags,
valid::{ValidationFlags, Validator},
};
use quote::quote;

#[derive(Debug, serde::Deserialize)]
Expand Down Expand Up @@ -91,19 +95,35 @@ fn wgsl(spv_filepath: impl AsRef<std::path::Path>, destination: impl AsRef<std::
});
let opts = naga::front::spv::Options::default();
let module = naga::front::spv::parse_u8_slice(&bytes, &opts).unwrap();
let mut validator =
naga::valid::Validator::new(Default::default(), naga::valid::Capabilities::empty());
let info = validator.validate(&module).unwrap_or_else(|e| {
panic!(
"Could not validate '{}': {e}",
spv_filepath.as_ref().display(),
)
});
let wgsl =
naga::back::wgsl::write_string(&module, &info, naga::back::wgsl::WriterFlags::empty())
.unwrap();
let mut wgsl = String::new();
let mut panic_msg: Option<String> = None;
for (vflags, name) in [
(ValidationFlags::empty(), "empty"),
(ValidationFlags::all(), "all"),
] {
let mut validator = Validator::new(vflags, Default::default());
match validator.validate(&module) {
Err(e) => {
panic_msg = Some(format!(
"Could not validate '{}' with WGSL validation flags {name}: {}",
spv_filepath.as_ref().display(),
e.emit_to_string(&wgsl)
));
}
Ok(i) => {
wgsl = naga::back::wgsl::write_string(&module, &i, WriterFlags::empty()).unwrap();
}
};
}

let destination = destination.as_ref().with_extension("wgsl");
std::fs::write(destination, wgsl).unwrap();
if let Some(msg) = panic_msg {
panic!(
"{msg}\nWGSL was written to {}",
spv_filepath.as_ref().display()
);
}
}

pub struct RenderlingPaths {
Expand Down
4 changes: 2 additions & 2 deletions crates/renderling-ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! Happy hacking!
use std::sync::{Arc, RwLock};

use craballoc::prelude::Hybrid;
use craballoc::prelude::{Hybrid, SourceId};
use crabslab::Id;
use glyph_brush::ab_glyph;
use renderling::{
Expand Down Expand Up @@ -150,7 +150,7 @@ pub struct Ui {
//
// The `usize` key here is the update source notifier index, which is needed
// to re-order after any transform performs an update.
transforms: Arc<RwLock<FxHashMap<usize, UiTransform>>>,
transforms: Arc<RwLock<FxHashMap<SourceId, UiTransform>>>,
default_stroke_options: Arc<RwLock<StrokeOptions>>,
default_fill_options: Arc<RwLock<FillOptions>>,
}
Expand Down
7 changes: 4 additions & 3 deletions crates/renderling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ quote.workspace = true
renderling_build = { path = "../renderling-build", version = "0.1.0" }
serde.workspace = true
serde_json.workspace = true
similarity.workspace = true

# dependencies for CPU and GPU code
[dependencies]
Expand Down Expand Up @@ -73,15 +74,15 @@ wgpu = { workspace = true, features = ["spirv"] }
winit = { workspace = true, optional = true }

[dev-dependencies]
acorn_prng.workspace = true
assert_approx_eq = {workspace = true}
assert_approx_eq.workspace = true
ctor = "0.2.2"
env_logger = {workspace = true}
env_logger.workspace = true
example = { path = "../example" }
fastrand = "2.1.1"
icosahedron = "0.1"
img-diff = { path = "../img-diff" }
naga.workspace = true
plotters.workspace = true
ttf-parser = "0.20.0"
wgpu-core.workspace = true
winit.workspace = true
Expand Down
Binary file modified crates/renderling/shaders/atlas-atlas_blit_vertex.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/bloom-bloom_downsample_fragment.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/bloom-bloom_mix_fragment.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/bloom-bloom_upsample_fragment.spv
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/renderling/shaders/cull-compute_culling.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/debug-debug_overlay_fragment.spv
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/renderling/shaders/light-shadow_mapping_vertex.spv
Binary file not shown.
15 changes: 15 additions & 0 deletions crates/renderling/shaders/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@
"entry_point": "ibl::diffuse_irradiance::di_convolution_fragment",
"wgsl_entry_point": "ibldiffuse_irradiancedi_convolution_fragment"
},
{
"source_path": "shaders/light-light_tiling_compute_tiles.spv",
"entry_point": "light::light_tiling_compute_tiles",
"wgsl_entry_point": "lightlight_tiling_compute_tiles"
},
{
"source_path": "shaders/light-light_tiling_compute_tiles_multisampled.spv",
"entry_point": "light::light_tiling_compute_tiles_multisampled",
"wgsl_entry_point": "lightlight_tiling_compute_tiles_multisampled"
},
{
"source_path": "shaders/light-light_tiling_depth_pre_pass.spv",
"entry_point": "light::light_tiling_depth_pre_pass",
"wgsl_entry_point": "lightlight_tiling_depth_pre_pass"
},
{
"source_path": "shaders/light-shadow_mapping_fragment.spv",
"entry_point": "light::shadow_mapping_fragment",
Expand Down
Binary file modified crates/renderling/shaders/skybox-skybox_cubemap_fragment.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/skybox-skybox_cubemap_vertex.spv
Binary file not shown.
Binary file not shown.
Binary file modified crates/renderling/shaders/skybox-skybox_vertex.spv
Binary file not shown.
Binary file added crates/renderling/shaders/stage-go_thing.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/stage-renderlet_fragment.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/stage-renderlet_vertex.spv
Binary file not shown.
Binary file modified crates/renderling/shaders/tonemapping-tonemapping_fragment.spv
Binary file not shown.
3 changes: 1 addition & 2 deletions crates/renderling/src/bloom/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,7 @@ impl Bloom {
let runtime = runtime.as_ref();
let resolution = UVec2::new(hdr_texture.width(), hdr_texture.height());

let slab =
SlabAllocator::new_with_label(runtime, wgpu::BufferUsages::empty(), Some("bloom-slab"));
let slab = SlabAllocator::new(runtime, "bloom-slab", wgpu::BufferUsages::empty());
let downsample_pixel_sizes = slab.new_array(
config_resolutions(resolution).map(|r| 1.0 / Vec2::new(r.x as f32, r.y as f32)),
);
Expand Down
Loading
Loading