From 8c1581117cf18f14ee03d5c7812bc09a2ca8635e Mon Sep 17 00:00:00 2001 From: polymonster Date: Sat, 13 Jul 2024 13:05:10 +0100 Subject: [PATCH 1/2] - add new tests and update readme --- hotline-data | 2 +- plugins/ecs_examples/src/omni_shadow_map.rs | 160 +++++++++++++------- readme.md | 12 ++ tests/tests.rs | 10 ++ todo.txt | 12 +- 5 files changed, 136 insertions(+), 60 deletions(-) diff --git a/hotline-data b/hotline-data index a708d59..63f724b 160000 --- a/hotline-data +++ b/hotline-data @@ -1 +1 @@ -Subproject commit a708d59e1fff5bbef2103acc3c09dc8d7daeee53 +Subproject commit 63f724b64c59dc4ba049589d33ed431b1d092af2 diff --git a/plugins/ecs_examples/src/omni_shadow_map.rs b/plugins/ecs_examples/src/omni_shadow_map.rs index 0147275..140b6e4 100644 --- a/plugins/ecs_examples/src/omni_shadow_map.rs +++ b/plugins/ecs_examples/src/omni_shadow_map.rs @@ -17,6 +17,7 @@ pub fn omni_shadow_map(client: &mut Client Result<(), hotline_rs::Error> { let cube_mesh = hotline_rs::primitives::create_cube_mesh(&mut device.0); + let tourus_mesh = hotline_rs::primitives::create_tourus_mesh(&mut device.0, 32); + let helix_mesh = hotline_rs::primitives::create_helix_mesh(&mut device.0, 32, 4); + let tube_mesh = hotline_rs::primitives::create_tube_prism_mesh(&mut device.0, 32, 0, 32, true, true, 1.0, 0.66, 1.0); + let triangle_mesh = hotline_rs::primitives::create_tube_prism_mesh(&mut device.0, 3, 0, 3, false, true, 0.33, 0.66, 1.0); - let dim = 32; - let dim2 = dim / 2; - let tile_size = 10.0; - let height = 100.0; - let spacing = 16.0; - let extent = dim as f32 * tile_size * spacing; - let half_extent = extent / 2.0; + let bounds = 100.0; let sm = pmfx.get_texture("single_omni_shadow_map").unwrap(); - // spot light - let light_pos = vec3f(0.0, height * 0.5, 0.0); + // point light + let light_bounds = bounds * 0.75; + let light_pos = vec3f(light_bounds, light_bounds, 0.0); let light_radius = 256.0; commands.spawn(( Position(light_pos), Velocity(Vec3f::unit_z()), - Colour(vec4f(0.5, 0.25, 0.125, 1.0)), + Colour(vec4f(0.125, 0.5, 0.25, 1.0)), LightComponent { light_type: LightType::Point, radius: light_radius, @@ -68,37 +68,88 @@ pub fn setup_omni_shadow_map( ..Default::default() }); - let offset = (tile_size + spacing) * 3.0; - let start = vec3f(-half_extent, height, -half_extent) + vec3f(offset, 0.0, offset); - let mut pos = start; - - for y in 0..dim { - pos.x = start.x; - for x in 0..dim { - commands.spawn(( - Position(pos), - Scale(vec3f(tile_size, height, tile_size)), - Rotation(Quatf::identity()), - MeshComponent(cube_mesh.clone()), - WorldMatrix(Mat34f::identity()) - )); - - pos.x += tile_size * spacing; - } + let shape_bounds = bounds * 0.6; - pos.z += tile_size * spacing - } + // tourus + let tourus_size = bounds * 0.1; + commands.spawn(( + Position(vec3f(shape_bounds * -0.75, shape_bounds * 0.7, -shape_bounds * 0.1)), + Scale(splat3f(tourus_size)), + Rotation(Quatf::identity()), + MeshComponent(tourus_mesh.clone()), + WorldMatrix(Mat34f::identity()) + )); - // ground plane - let plane_mesh = hotline_rs::primitives::create_plane_mesh(&mut device.0, 1); + // helix + commands.spawn(( + Position(vec3f(shape_bounds * -0.3, shape_bounds * -0.6, shape_bounds * 0.8)), + Scale(splat3f(tourus_size * 2.0)), + Rotation(Quatf::identity()), + MeshComponent(helix_mesh.clone()), + WorldMatrix(Mat34f::identity()) + )); + + // tube + commands.spawn(( + Position(vec3f(shape_bounds * 1.0, shape_bounds * 0.1, shape_bounds * -1.0)), + Scale(splat3f(tourus_size)), + Rotation(Quatf::identity()), + MeshComponent(tube_mesh.clone()), + WorldMatrix(Mat34f::identity()) + )); + // tri prsim commands.spawn(( - Position(Vec3f::zero()), - Scale(vec3f(half_extent, 1.0, half_extent)), + Position(vec3f(shape_bounds * 0.123, shape_bounds * -0.6, shape_bounds * -0.8)), + Scale(splat3f(tourus_size * 2.0)), Rotation(Quatf::identity()), - MeshComponent(plane_mesh.clone()), + MeshComponent(triangle_mesh.clone()), WorldMatrix(Mat34f::identity()) )); + + // walls + let thickness = bounds * 0.1; + let face_size = bounds * 2.0; + + // -y + commands.spawn(( + Position(vec3f(0.0, -bounds, 0.0)), + Scale(vec3f(face_size, thickness, face_size)), + Rotation(Quatf::identity()), + MeshComponent(cube_mesh.clone()), + WorldMatrix(Mat34f::identity()), + Billboard + )); + + // + y + commands.spawn(( + Position(vec3f(0.0, bounds, 0.0)), + Scale(vec3f(face_size, thickness, face_size)), + Rotation(Quatf::identity()), + MeshComponent(cube_mesh.clone()), + WorldMatrix(Mat34f::identity()), + Billboard + )); + + // -z + commands.spawn(( + Position(vec3f(0.0, 0.0, -bounds)), + Scale(vec3f(face_size, face_size, thickness)), + Rotation(Quatf::identity()), + MeshComponent(cube_mesh.clone()), + WorldMatrix(Mat34f::identity()), + Billboard + )); + + // -x + commands.spawn(( + Position(vec3f(-bounds, 0.0, 0.0)), + Scale(vec3f(thickness, face_size, face_size)), + Rotation(Quatf::identity()), + MeshComponent(cube_mesh.clone()), + WorldMatrix(Mat34f::identity()), + Billboard + )); pmfx.update_cubemap_camera_constants("omni_shadow_camera", light_pos, 0.1, light_radius * 2.0); @@ -112,35 +163,28 @@ pub fn animate_omni_shadow ( mut pmfx: ResMut, mut light_query: Query<(&mut Position, &mut Velocity, &LightComponent)>) -> Result<(), hotline_rs::Error> { - let dim = 32; - let dim2 = dim / 2; - let tile_size = 10.0; - let spacing = 16.0; - - let extent = (tile_size + spacing) * 3.0 * 6.0; + let extent = 60.0; for (mut position, mut velocity, component) in &mut light_query { - position.0 += velocity.0 * time.delta * 400.0; - - if position.z > extent { - velocity.0 = Vec3f::unit_x(); - } - - if position.x > extent { - velocity.0 = -Vec3f::unit_z(); - } - - if position.z < -extent { - velocity.0 = -Vec3f::unit_x(); - } - - if position.x < -extent { - velocity.0 = Vec3f::unit_z(); - } + position.0 = vec3f(sin(time.accumulated), cos(time.accumulated), cos(time.accumulated)) * extent; pmfx.update_cubemap_camera_constants("omni_shadow_camera", position.0, 0.1, component.radius * 2.0); } Ok(()) -} \ No newline at end of file +} + +#[no_mangle] +#[export_update_fn] +pub fn animate_meshes ( + time: Res, + mut pmfx: ResMut, + mut mesh_query: Query<(&mut Rotation, &MeshComponent), Without>) -> Result<(), hotline_rs::Error> { + + for (mut rotation, component) in &mut mesh_query { + rotation.0 *= Quat::from_euler_angles(f32::pi() * time.delta, f32::pi() * time.delta, f32::pi() * time.delta); + } + + Ok(()) +} diff --git a/readme.md b/readme.md index b9ac563..224c2cd 100644 --- a/readme.md +++ b/readme.md @@ -959,6 +959,18 @@ A sample to demonstrate how to configure a single shadow map with a vertex shade Demonstrates how multiple cubemap faces can be rendered using cubemap cameras and then sampled from to create dynamic environment mapped reflections. A single `pmfx` view is created with the `cubemap` flag set to true, this will automatically create 6 child views for each face of the cubemap. +### Omni Shadow Map + + + +Demonstrates how multiple cubemap faces can be rendered using cubemap cameras and comparison sampled with PCF to create a point light shadow. A single `pmfx` depth only view is created with the `cubemap` flag set to true, this will automatically create 6 child views for each face of the cubemap. + +### PBR + + + +An implementation of physically based rendering with image based lighting. Note that currently the cubemap pre-filtering is just using the mip levels, in time there will be an improved pipeline to properly pre-filter. + ## Tests There are standalone tests and client/plugin tests to test graphics API features. This requires a test runner which has a GPU and is not headless, so I am using my home machine as a self-hosted actions runner. You can run the tests yourself but because of the requirement of a GPU device and plugin loading the tests need to be ran single threaded. diff --git a/tests/tests.rs b/tests/tests.rs index 827cb29..d24f814 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -766,4 +766,14 @@ fn shadow_map() -> Result<(), hotline_rs::Error> { #[test] fn dynamic_cubemap() -> Result<(), hotline_rs::Error> { boot_client_ecs_plugin_demo("dynamic_cubemap") +} + +#[test] +fn pbr() -> Result<(), hotline_rs::Error> { + boot_client_ecs_plugin_demo("pbr") +} + +#[test] +fn omni_shadow_maps() -> Result<(), hotline_rs::Error> { + boot_client_ecs_plugin_demo("omni_shadow_map") } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 993f682..41e2364 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,7 @@ // TODO: +// samples // - omni shadow map - // - clear buffer (uav) // - buffers in pmfx // - clear buffers for compute @@ -12,8 +12,15 @@ // - area light // - disney brdf +// platforms +// - integrate macos changes and fixup win32/d3d12 +// - test shader compilation with mac changes + // engine // - reverse depth +// - visibility buffer +// - mesh shader +// - hello triangle (ray tracing) // - HDR pipeline // - glft // - set name on resources @@ -31,6 +38,9 @@ // - view menu + saving state // - imgui not tracked within draw call stats +// build +// - update pmbuild + // DONE: // x texture formats (BC etc) // x texture load image from file into pmfx From 4f75fe0de6b035fd786db8dc01c070d2a1ff4db3 Mon Sep 17 00:00:00 2001 From: polymonster Date: Sat, 13 Jul 2024 13:11:08 +0100 Subject: [PATCH 2/2] - update todo --- todo.txt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/todo.txt b/todo.txt index 41e2364..2ff0447 100644 --- a/todo.txt +++ b/todo.txt @@ -1,20 +1,23 @@ // TODO: +// issues +// - swap between dynamic cube and PBR causes inconsitency in the cubemap texture + // samples -// - omni shadow map // - clear buffer (uav) // - buffers in pmfx // - clear buffers for compute -// material system +// effects // - perspective shadow map // - cascaded shadow map // - area light // - disney brdf // platforms +// - bring across macos shader compilation // - integrate macos changes and fixup win32/d3d12 -// - test shader compilation with mac changes +// - try update windows-rs // engine // - reverse depth @@ -39,9 +42,11 @@ // - imgui not tracked within draw call stats // build -// - update pmbuild // DONE: +// x test shader compilation with mac changes +// x update pmbuild +// x omni shadow map // x texture formats (BC etc) // x texture load image from file into pmfx // x copy texture region