render: PCF with poisson disc on directional lights
This commit is contained in:
parent
27bc88c5a7
commit
4c6c6c4dd5
|
@ -65,6 +65,24 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned-array"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c92d086290f52938013f6242ac62bf7d401fab8ad36798a609faa65c3fd2c"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
|
@ -122,6 +140,15 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.37.3+1.3.251"
|
||||
|
@ -351,6 +378,12 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "az"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
|
@ -786,6 +819,12 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "divrem"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69dde51e8fef5e12c1d65e0929b03d66e4c0c18282bc30ed2ca050ad6f44dd82"
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
|
@ -795,6 +834,12 @@ dependencies = [
|
|||
"libloading 0.8.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.0"
|
||||
|
@ -807,6 +852,12 @@ version = "1.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "elapsed"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f4e5af126dafd0741c2ad62d47f68b28602550102e5f0dd45c8a97fc8b49c29"
|
||||
|
||||
[[package]]
|
||||
name = "elua"
|
||||
version = "0.1.0"
|
||||
|
@ -908,6 +959,18 @@ dependencies = [
|
|||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fast_poisson"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2472baa9796d2ee497bd61690e3093a26935390d8ce0dd0ddc2db9b47a65898f"
|
||||
dependencies = [
|
||||
"kiddo",
|
||||
"rand 0.8.5",
|
||||
"rand_distr",
|
||||
"rand_xoshiro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
|
@ -953,6 +1016,19 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixed"
|
||||
version = "1.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fc715d38bea7b5bf487fcd79bcf8c209f0b58014f3018a7a19c2b855f472048"
|
||||
dependencies = [
|
||||
"az",
|
||||
"bytemuck",
|
||||
"half",
|
||||
"num-traits",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixed-timestep-rotating-model"
|
||||
version = "0.1.0"
|
||||
|
@ -1683,6 +1759,26 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kiddo"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e1c5ea778d68eacd5c33f29537ba0b7b6c2595e74ee013a69cedc20ab4d3177"
|
||||
dependencies = [
|
||||
"aligned",
|
||||
"aligned-array",
|
||||
"az",
|
||||
"divrem",
|
||||
"doc-comment",
|
||||
"elapsed",
|
||||
"fixed",
|
||||
"log",
|
||||
"min-max-heap",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.8"
|
||||
|
@ -1750,6 +1846,12 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.0.2"
|
||||
|
@ -1868,6 +1970,7 @@ dependencies = [
|
|||
"bind_match",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"fast_poisson",
|
||||
"gilrs-core",
|
||||
"glam",
|
||||
"image",
|
||||
|
@ -2079,6 +2182,12 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "min-max-heap"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2687e6cf9c00f48e9284cf9fd15f2ef341d03cc7743abf9df4c5f07fdee50b18"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
|
@ -2286,6 +2395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2727,6 +2837,25 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xoshiro"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.3"
|
||||
|
@ -3226,6 +3355,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
|
|
@ -6,7 +6,7 @@ use lyra_engine::{
|
|||
InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput,
|
||||
},
|
||||
math::{self, Transform, Vec3},
|
||||
render::light::{directional::DirectionalLight, PointLight},
|
||||
render::light::directional::DirectionalLight,
|
||||
scene::{
|
||||
CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform,
|
||||
ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN,
|
||||
|
@ -161,7 +161,7 @@ fn setup_scene_plugin(game: &mut Game) {
|
|||
DirectionalLight {
|
||||
enabled: true,
|
||||
color: Vec3::new(1.0, 0.95, 0.9),
|
||||
intensity: 0.5,
|
||||
intensity: 0.9,
|
||||
},
|
||||
light_tran,
|
||||
));
|
||||
|
|
|
@ -39,6 +39,7 @@ rustc-hash = "1.1.0"
|
|||
petgraph = { version = "0.6.5", features = ["matrix_graph"] }
|
||||
bind_match = "0.1.2"
|
||||
round_mult = "0.1.3"
|
||||
fast_poisson = { version = "1.0.0", features = ["single_precision"] }
|
||||
|
||||
[features]
|
||||
tracy = ["dep:tracing-tracy"]
|
||||
|
|
|
@ -125,6 +125,11 @@ impl Node for MeshPass {
|
|||
.expect("missing ShadowMapsPassSlots::ShadowLightUniformsBuffer")
|
||||
.as_buffer()
|
||||
.unwrap();
|
||||
let pcf_poisson_disc = graph
|
||||
.slot_value(ShadowMapsPassSlots::PcfPoissonDiscBuffer)
|
||||
.expect("missing ShadowMapsPassSlots::PcfPoissonDiscBuffer")
|
||||
.as_buffer()
|
||||
.unwrap();
|
||||
|
||||
let atlas_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("bgl_shadows_atlas"),
|
||||
|
@ -165,6 +170,16 @@ impl Node for MeshPass {
|
|||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 4,
|
||||
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Storage { read_only: true },
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -196,6 +211,14 @@ impl Node for MeshPass {
|
|||
size: None,
|
||||
}),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 4,
|
||||
resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
|
||||
buffer: pcf_poisson_disc,
|
||||
offset: 0,
|
||||
size: None,
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use std::{
|
||||
collections::VecDeque,
|
||||
mem,
|
||||
rc::Rc,
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
collections::VecDeque, mem, rc::Rc, sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}
|
||||
};
|
||||
|
||||
use fast_poisson::Poisson2D;
|
||||
use itertools::Itertools;
|
||||
use lyra_ecs::{
|
||||
query::{filter::Has, Entities},
|
||||
AtomicRef, Component, Entity, ResourceData,
|
||||
|
@ -16,12 +15,17 @@ use tracing::warn;
|
|||
use wgpu::util::DeviceExt;
|
||||
|
||||
use crate::render::{
|
||||
graph::{Node, NodeDesc, NodeType, SlotAttribute, SlotValue}, light::{directional::DirectionalLight, LightType, PointLight}, resource::{FragmentState, RenderPipeline, RenderPipelineDescriptor, Shader, VertexState}, transform_buffer_storage::TransformBuffers, vertex::Vertex, AtlasFrame, GpuSlotBuffer, TextureAtlas
|
||||
graph::{Node, NodeDesc, NodeType, SlotAttribute, SlotValue},
|
||||
light::{directional::DirectionalLight, LightType, PointLight},
|
||||
resource::{FragmentState, RenderPipeline, RenderPipelineDescriptor, Shader, VertexState},
|
||||
transform_buffer_storage::TransformBuffers,
|
||||
vertex::Vertex,
|
||||
AtlasFrame, GpuSlotBuffer, TextureAtlas,
|
||||
};
|
||||
|
||||
use super::{MeshBufferStorage, RenderAssets, RenderMeshes};
|
||||
|
||||
const PCF_SAMPLES_NUM: u32 = 4;
|
||||
const PCF_SAMPLES_NUM: u32 = 6;
|
||||
const SHADOW_SIZE: glam::UVec2 = glam::uvec2(1024, 1024);
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, RenderGraphLabel)]
|
||||
|
@ -32,6 +36,7 @@ pub enum ShadowMapsPassSlots {
|
|||
ShadowAtlasSizeBuffer,
|
||||
ShadowLightUniformsBuffer,
|
||||
ShadowSettingsUniform,
|
||||
PcfPoissonDiscBuffer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, RenderGraphLabel)]
|
||||
|
@ -174,8 +179,7 @@ impl ShadowMapsPass {
|
|||
let atlas_index = atlas
|
||||
.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.expect("failed to pack new shadow map into texture atlas");
|
||||
let atlas_frame = atlas.texture_frame(atlas_index)
|
||||
.expect("Frame missing");
|
||||
let atlas_frame = atlas.texture_frame(atlas_index).expect("Frame missing");
|
||||
|
||||
let projection =
|
||||
glam::Mat4::orthographic_rh(-10.0, 10.0, -10.0, 10.0, NEAR_PLANE, FAR_PLANE);
|
||||
|
@ -253,24 +257,12 @@ impl ShadowMapsPass {
|
|||
),
|
||||
];
|
||||
|
||||
let atlas_idx_1 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_2 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_3 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_4 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_5 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_6 =
|
||||
atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _)
|
||||
.unwrap();
|
||||
let atlas_idx_1 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
let atlas_idx_2 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
let atlas_idx_3 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
let atlas_idx_4 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
let atlas_idx_5 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
let atlas_idx_6 = atlas.pack(SHADOW_SIZE.x as _, SHADOW_SIZE.y as _).unwrap();
|
||||
|
||||
let frames = [
|
||||
atlas.texture_frame(atlas_idx_1).unwrap(),
|
||||
|
@ -325,6 +317,37 @@ impl ShadowMapsPass {
|
|||
fn mesh_buffers(&self) -> AtomicRef<RenderAssets<MeshBufferStorage>> {
|
||||
self.mesh_buffers.as_ref().unwrap().get()
|
||||
}
|
||||
|
||||
/// Create the gpu buffer for a poisson disc
|
||||
fn create_poisson_disc_buffer(&self, device: &wgpu::Device, label: &str, num_samples: u32) -> wgpu::Buffer {
|
||||
device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some(label),
|
||||
size: mem::size_of::<glam::Vec2>() as u64 * (num_samples.pow(2)) as u64,
|
||||
usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate and write a Poisson disc to `buffer` with `num_pcf_samples.pow(2)` amount of points.
|
||||
fn write_poisson_disc(&self, queue: &wgpu::Queue, buffer: &wgpu::Buffer, num_pcf_samples: u32) {
|
||||
let num_points = num_pcf_samples.pow(2);
|
||||
let num_floats = num_points * 2; // points are vec2f
|
||||
let min_dist = (num_floats as f32).sqrt() / num_floats as f32;
|
||||
let mut points = vec![];
|
||||
|
||||
// use a while loop to ensure that the correct number of floats is created
|
||||
while points.len() < num_floats as usize {
|
||||
let poisson = Poisson2D::new()
|
||||
.with_dimensions([1.0, 1.0], min_dist)
|
||||
.with_samples(num_pcf_samples);
|
||||
|
||||
points = poisson.iter().flatten().collect_vec();
|
||||
|
||||
}
|
||||
points.truncate(num_floats as _);
|
||||
|
||||
queue.write_buffer(buffer, 0, bytemuck::cast_slice(points.as_slice()));
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ShadowMapsPass {
|
||||
|
@ -368,7 +391,8 @@ impl Node for ShadowMapsPass {
|
|||
Some(SlotValue::Buffer(self.atlas_size_buffer.clone())),
|
||||
);
|
||||
|
||||
let settings_buffer = graph.device().create_buffer(&wgpu::BufferDescriptor {
|
||||
let device = graph.device();
|
||||
let settings_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("buffer_shadow_settings"),
|
||||
size: mem::size_of::<ShadowSettingsUniform>() as _,
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
|
@ -380,6 +404,14 @@ impl Node for ShadowMapsPass {
|
|||
Some(SlotValue::Buffer(Arc::new(settings_buffer))),
|
||||
);
|
||||
|
||||
node.add_buffer_slot(
|
||||
ShadowMapsPassSlots::PcfPoissonDiscBuffer,
|
||||
SlotAttribute::Output,
|
||||
Some(SlotValue::Buffer(Arc::new(
|
||||
self.create_poisson_disc_buffer(device, "buffer_poisson_disc_pcf", PCF_SAMPLES_NUM),
|
||||
))),
|
||||
);
|
||||
|
||||
node
|
||||
}
|
||||
|
||||
|
@ -390,9 +422,20 @@ impl Node for ShadowMapsPass {
|
|||
context: &mut crate::render::graph::RenderGraphContext,
|
||||
) {
|
||||
{
|
||||
// TODO: Update the poisson disc every time the PCF sampling point number changed
|
||||
if !world.has_resource::<ShadowSettings>() {
|
||||
let buffer = graph.slot_value(ShadowMapsPassSlots::PcfPoissonDiscBuffer)
|
||||
.unwrap().as_buffer().unwrap();
|
||||
self.write_poisson_disc(&context.queue, &buffer, ShadowSettings::default().pcf_samples_num);
|
||||
}
|
||||
|
||||
// TODO: only write buffer on changes to resource
|
||||
let shadow_settings = world.get_resource_or_default::<ShadowSettings>();
|
||||
context.queue_buffer_write_with(ShadowMapsPassSlots::ShadowSettingsUniform, 0, ShadowSettingsUniform::from(*shadow_settings));
|
||||
context.queue_buffer_write_with(
|
||||
ShadowMapsPassSlots::ShadowSettingsUniform,
|
||||
0,
|
||||
ShadowSettingsUniform::from(*shadow_settings),
|
||||
);
|
||||
}
|
||||
|
||||
self.render_meshes = world.try_get_resource_data::<RenderMeshes>();
|
||||
|
@ -425,8 +468,13 @@ impl Node for ShadowMapsPass {
|
|||
for (entity, pos, _) in world.view_iter::<(Entities, &Transform, Has<DirectionalLight>)>() {
|
||||
if !self.depth_maps.contains_key(&entity) {
|
||||
// TODO: dont pack the textures as they're added
|
||||
let atlas_index =
|
||||
self.create_depth_map(&context.queue, LightType::Directional, entity, *pos, 45.0);
|
||||
let atlas_index = self.create_depth_map(
|
||||
&context.queue,
|
||||
LightType::Directional,
|
||||
entity,
|
||||
*pos,
|
||||
45.0,
|
||||
);
|
||||
index_components_queue.push_back((entity, atlas_index));
|
||||
}
|
||||
}
|
||||
|
@ -553,12 +601,12 @@ impl Node for ShadowMapsPass {
|
|||
});
|
||||
|
||||
for light_depth_map in self.depth_maps.values() {
|
||||
|
||||
match light_depth_map.light_type {
|
||||
LightType::Directional => {
|
||||
pass.set_pipeline(&pipeline);
|
||||
|
||||
let frame = atlas.texture_frame(light_depth_map.atlas_index)
|
||||
let frame = atlas
|
||||
.texture_frame(light_depth_map.atlas_index)
|
||||
.expect("missing atlas frame for light");
|
||||
|
||||
light_shadow_pass_impl(
|
||||
|
@ -570,12 +618,13 @@ impl Node for ShadowMapsPass {
|
|||
&frame,
|
||||
light_depth_map.uniform_index[0] as _,
|
||||
);
|
||||
},
|
||||
}
|
||||
LightType::Point => {
|
||||
pass.set_pipeline(&point_light_pipeline);
|
||||
|
||||
for side in 0..6 {
|
||||
let frame = atlas.texture_frame(light_depth_map.atlas_index + side)
|
||||
let frame = atlas
|
||||
.texture_frame(light_depth_map.atlas_index + side)
|
||||
.expect("missing atlas frame of light");
|
||||
let ui = light_depth_map.uniform_index[side as usize];
|
||||
|
||||
|
@ -589,7 +638,7 @@ impl Node for ShadowMapsPass {
|
|||
ui as _,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
LightType::Spotlight => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -714,7 +763,9 @@ pub struct ShadowSettings {
|
|||
|
||||
impl Default for ShadowSettings {
|
||||
fn default() -> Self {
|
||||
Self { pcf_samples_num: PCF_SAMPLES_NUM }
|
||||
Self {
|
||||
pcf_samples_num: PCF_SAMPLES_NUM,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ impl LightUniformBuffers {
|
|||
lights.push(uniform);
|
||||
}
|
||||
|
||||
assert!(lights.len() < self.max_light_count as _); // ensure we dont overwrite the buffer
|
||||
assert!(lights.len() < self.max_light_count as usize); // ensure we dont overwrite the buffer
|
||||
|
||||
// write the amount of lights to the buffer, and right after that the list of lights.
|
||||
queue.write_buffer(&self.buffer, 0, bytemuck::cast_slice(&[lights.len()]));
|
||||
|
|
|
@ -137,6 +137,8 @@ var s_shadow_maps_atlas: sampler_comparison;
|
|||
var<uniform> u_shadow_settings: ShadowSettingsUniform;
|
||||
@group(5) @binding(3)
|
||||
var<storage, read> u_light_shadow: array<LightShadowMapUniform>;
|
||||
@group(5) @binding(4)
|
||||
var<storage, read> u_pcf_poisson_disc: array<vec2<f32>>;
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
|
@ -287,11 +289,16 @@ fn pcf_dir_light(tex_coords: vec2<f32>, test_depth: f32, shadow_u: LightShadowMa
|
|||
|
||||
// Sample PCF
|
||||
var shadow = 0.0;
|
||||
var i = 0;
|
||||
for (var x = -half_filter_size; x <= half_filter_size; x += 1.0) {
|
||||
for (var y = -half_filter_size; y <= half_filter_size; y += 1.0) {
|
||||
let offset = tex_coords + vec2<f32>(x, y) * texel_size;
|
||||
//let random = u_pcf_poisson_disc[i] * texel_size;
|
||||
let offset = tex_coords + (u_pcf_poisson_disc[i] + vec2<f32>(x, y)) * texel_size;
|
||||
|
||||
let pcf_depth = textureSampleCompare(t_shadow_maps_atlas, s_shadow_maps_atlas, offset, test_depth);
|
||||
shadow += pcf_depth;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
shadow /= pow(f32(u_shadow_settings.pcf_samples_num), 2.0);
|
||||
|
|
|
@ -198,7 +198,7 @@ impl SkylinePacker {
|
|||
/* if r.bottom() < min_height
|
||||
|| (r.bottom() == min_height && self.skylines[i].width < min_width as usize) */
|
||||
if y + height < min_height ||
|
||||
(y + height == min_height && self.skylines[i].width < min_width as _)
|
||||
(y + height == min_height && self.skylines[i].width < min_width as usize)
|
||||
{
|
||||
min_height = y + height;
|
||||
min_width = self.skylines[i].width as _;
|
||||
|
@ -224,8 +224,8 @@ impl SkylinePacker {
|
|||
width: frame.width as _
|
||||
};
|
||||
|
||||
assert!(skyline.right() <= self.size.x as _);
|
||||
assert!(skyline.y <= self.size.y as _);
|
||||
assert!(skyline.right() <= self.size.x as usize);
|
||||
assert!(skyline.y <= self.size.y as usize);
|
||||
|
||||
self.skylines.insert(i, skyline);
|
||||
|
||||
|
|
Loading…
Reference in New Issue