,
}
-impl DiReservoir {
- pub fn read(buffer: &[Vec4], id: usize) -> Self {
- let d0 = unsafe { *buffer.index_unchecked(2 * id) };
- let d1 = unsafe { *buffer.index_unchecked(2 * id + 1) };
- let [is_occluded, confidence, ..] = d0.w.to_bits().to_bytes();
+#[repr(C)]
+#[derive(Clone, Copy, Default)]
+pub struct DiReservoirData {
+ pub m: f32,
+ pub w: f32,
+ pub pdf: f32,
+ pub confidence: f32,
+ pub is_occluded: u32,
+ pub light_id: u32,
+ // Add padding to align `light_point` to 16 bytes
+ _padding0: [u32; 2],
+ pub light_point: Vec3
+}
+impl DiReservoir {
+ pub fn read(buffer: &[DiReservoirData], id: usize) -> Self {
+ let data = unsafe { *buffer.index_unchecked(id) };
Self {
reservoir: Reservoir {
sample: DiSample {
- pdf: d0.z,
- confidence: confidence as f32,
- light_id: LightId::new(d1.w.to_bits()),
- light_point: d1.xyz(),
- is_occluded: is_occluded > 0,
+ pdf: data.pdf,
+ confidence: data.confidence,
+ light_id: LightId::new(data.light_id),
+ light_point: data.light_point,
+ is_occluded: data.is_occluded != 0,
},
- m: d0.x,
- w: d0.y,
+ m: data.m,
+ w: data.w,
},
}
}
- pub fn write(self, buffer: &mut [Vec4], id: usize) {
- let d0 = vec4(
- self.reservoir.m,
- self.reservoir.w,
- self.sample.pdf,
- f32::from_bits(u32::from_bytes([
- self.sample.is_occluded as u32,
- self.sample.confidence as u32,
- 0,
- 0,
- ])),
- );
-
- let d1 = self
- .sample
- .light_point
- .extend(f32::from_bits(self.sample.light_id.get()));
-
+ pub fn write(self, buffer: &mut [DiReservoirData], id: usize) {
+ let data = DiReservoirData {
+ m: self.reservoir.m,
+ w: self.reservoir.w,
+ pdf: self.sample.pdf,
+ confidence: self.sample.confidence,
+ is_occluded: self.sample.is_occluded as u32,
+ light_id: self.sample.light_id.get(),
+ _padding0: [0u32; 2],
+ light_point: self.sample.light_point
+ };
unsafe {
- *buffer.index_unchecked_mut(2 * id) = d0;
- *buffer.index_unchecked_mut(2 * id + 1) = d1;
+ *buffer.index_unchecked_mut(id) = data;
}
}
- pub fn copy(input: &[Vec4], output: &mut [Vec4], id: usize) {
+ pub fn copy(input: &[DiReservoirData], output: &mut [DiReservoirData], id: usize) {
// TODO optimize
Self::read(input, id).write(output, id);
}
@@ -119,7 +122,7 @@ impl DiSample {
pub fn ray(self, hit_point: Vec3) -> Ray {
let dir = hit_point - self.light_point;
- Ray::new(self.light_point, dir.normalize()).with_len(dir.length())
+ Ray::new(self.light_point, crate::safe_normalize(dir)).with_len(dir.length())
}
}
@@ -147,7 +150,7 @@ mod tests {
}
}
- let mut buffer = [Vec4::ZERO; 2 * 10];
+ let mut buffer = [DiReservoirData::default(), DiReservoirData::default()];
for idx in 0..10 {
target(idx).write(&mut buffer, idx);
diff --git a/strolle-gpu/src/surface.rs b/strolle-gpu/src/surface.rs
index 0df86b20..6768121f 100644
--- a/strolle-gpu/src/surface.rs
+++ b/strolle-gpu/src/surface.rs
@@ -1,4 +1,4 @@
-use glam::{UVec2, Vec3, Vec4Swizzles};
+use glam::{UVec2, Vec2, Vec3, Vec4Swizzles};
#[cfg(target_arch = "spirv")]
use spirv_std::num_traits::Float;
@@ -60,10 +60,19 @@ impl<'a> SurfaceMap<'a> {
pub fn get(self, screen_pos: UVec2) -> Surface {
let d0 = self.tex.read(screen_pos);
+ let depth = d0.x;
+ let normal = Normal::decode(Vec2::new(d0.y, d0.z));
+
+ let packed = d0.w.to_bits();
+ let roughness_u = (packed >> 16) & 0xFF;
+ let roughness = roughness_u as f32 / 255.0;
+
Surface {
- normal: Normal::decode(d0.xy()),
- depth: d0.z,
- roughness: d0.w,
+ normal: normal,
+ depth: depth,
+ roughness: roughness,
}
}
}
+
+
diff --git a/strolle-gpu/src/triangle.rs b/strolle-gpu/src/triangle.rs
index bf52d5a5..f694c2ca 100644
--- a/strolle-gpu/src/triangle.rs
+++ b/strolle-gpu/src/triangle.rs
@@ -70,7 +70,7 @@ impl Triangle {
let pvec = ray.dir().cross(v0v2);
let det = v0v1.dot(pvec);
- if det.abs() < f32::EPSILON {
+ if det.abs() < crate::STROLLE_EPSILON {
return false;
}
diff --git a/strolle-gpu/src/utils.rs b/strolle-gpu/src/utils.rs
index 36b6bdd8..0de4684a 100644
--- a/strolle-gpu/src/utils.rs
+++ b/strolle-gpu/src/utils.rs
@@ -6,7 +6,7 @@ mod vec3_ext;
use core::ops;
-use glam::{uvec2, UVec2};
+use glam::{uvec2, UVec2, Vec3};
use spirv_std::Image;
pub use self::bilinear_filter::*;
@@ -41,3 +41,26 @@ pub fn resolve_checkerboard_alt(global_id: UVec2, frame: u32) -> UVec2 {
pub fn got_checkerboard_at(screen_pos: UVec2, frame: u32) -> bool {
screen_pos == resolve_checkerboard(screen_pos / uvec2(2, 1), frame)
}
+
+pub fn safe_normalize(v: Vec3) -> Vec3 {
+ let len = v.length();
+ if len > 0.0 && len < 1_000_000.0 {
+ v / len
+ } else {
+ Vec3::ZERO
+ }
+}
+
+pub fn safe_any_orthonormal_pair(normal: Vec3) -> (Vec3, Vec3) {
+ // Choose a helper vector that is not parallel to the normal
+ let helper = if normal.x * normal.x > normal.z * normal.z {
+ Vec3::new(normal.y, -normal.x, 0.0)
+ } else {
+ Vec3::new(0.0, -normal.z, normal.y)
+ };
+ let tangent = safe_normalize(normal.cross(helper));
+ let bitangent = normal.cross(tangent);
+ (tangent, bitangent)
+}
+
+pub const STROLLE_EPSILON: f32 = 0.000_0001;
\ No newline at end of file
diff --git a/strolle-gpu/src/utils/f32_ext.rs b/strolle-gpu/src/utils/f32_ext.rs
index 9d989195..6ab0f6dc 100644
--- a/strolle-gpu/src/utils/f32_ext.rs
+++ b/strolle-gpu/src/utils/f32_ext.rs
@@ -21,7 +21,7 @@ impl F32Ext for f32 {
}
fn inverse_sqrt(self) -> Self {
- 1.0 / self.sqrt()
+ 1.0 / self.max(crate::STROLLE_EPSILON).sqrt()
}
fn acos_approx(self) -> Self {
diff --git a/strolle-shader-builder/Cargo.toml b/strolle-shader-builder/Cargo.toml
index 46e34ed0..13f84289 100644
--- a/strolle-shader-builder/Cargo.toml
+++ b/strolle-shader-builder/Cargo.toml
@@ -4,4 +4,4 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-spirv-builder = { git = "https://github.com/EmbarkStudios/rust-gpu" }
+spirv-builder = { git = "https://github.com/glasspangolin/rust-gpu.git" }
diff --git a/strolle-shaders/Cargo.toml b/strolle-shaders/Cargo.toml
index b78e2dfb..61f193c6 100644
--- a/strolle-shaders/Cargo.toml
+++ b/strolle-shaders/Cargo.toml
@@ -11,4 +11,4 @@ crate-type = ["dylib"]
strolle-gpu = { path = "../strolle-gpu" }
# Crates.io
-spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu" }
+spirv-std = { git = "https://github.com/glasspangolin/rust-gpu.git" }
\ No newline at end of file
diff --git a/strolle-shaders/src/di_resolving.rs b/strolle-shaders/src/di_resolving.rs
index 6ae809cc..561b8c25 100644
--- a/strolle-shaders/src/di_resolving.rs
+++ b/strolle-shaders/src/di_resolving.rs
@@ -24,11 +24,11 @@ pub fn main(
#[spirv(descriptor_set = 1, binding = 4)]
atmosphere_sky_lut_sampler: &Sampler,
#[spirv(descriptor_set = 1, binding = 5)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 6)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 6)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 7, storage_buffer)]
- next_reservoirs: &[Vec4],
+ next_reservoirs: &[DiReservoirData],
#[spirv(descriptor_set = 1, binding = 8, storage_buffer)]
- prev_reservoirs: &mut [Vec4],
+ prev_reservoirs: &mut [DiReservoirData],
#[spirv(descriptor_set = 1, binding = 9)] diff_output: TexRgba32,
#[spirv(descriptor_set = 1, binding = 10)] spec_output: TexRgba32,
) {
@@ -62,8 +62,9 @@ pub fn main(
let mut res =
DiReservoir::read(next_reservoirs, camera.screen_to_idx(screen_pos));
- let confidence;
+ let confidence: f32;
let radiance;
+ let metallic;
if hit.is_some() {
let is_occluded = res.sample.ray(hit.point).intersect(
@@ -79,7 +80,7 @@ pub fn main(
confidence = if res.sample.is_occluded == is_occluded {
res.sample.confidence
} else {
- 0.0
+ 0.01
};
res.sample.confidence = 1.0;
@@ -90,18 +91,24 @@ pub fn main(
} else {
lights.get(res.sample.light_id).radiance(hit) * res.w
};
+
+ metallic = hit.gbuffer.metallic;
} else {
confidence = 1.0;
+ let dir = camera.ray(screen_pos).dir();
+
radiance = LightRadiance {
- radiance: atmosphere.sample(world.sun_dir(), hit.dir),
+ radiance: atmosphere.sample(world.sun_dir(), dir),
diff_brdf: Vec3::ONE,
spec_brdf: Vec3::ZERO,
};
+
+ metallic = 0.0;
};
unsafe {
- let diff_brdf = (1.0 - hit.gbuffer.metallic) / PI;
+ let diff_brdf = (1.0 - metallic) * (1.0 / PI);
let spec_brdf = radiance.spec_brdf;
diff_output.write(
diff --git a/strolle-shaders/src/di_sampling.rs b/strolle-shaders/src/di_sampling.rs
index 5351dd0a..1c5a2c94 100644
--- a/strolle-shaders/src/di_sampling.rs
+++ b/strolle-shaders/src/di_sampling.rs
@@ -19,9 +19,9 @@ pub fn main(
#[spirv(descriptor_set = 0, binding = 7, uniform)] world: &World,
#[spirv(descriptor_set = 1, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 1, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 3, storage_buffer)]
- out_reservoirs: &mut [Vec4],
+ out_reservoirs: &mut [DiReservoirData],
) {
let screen_pos = global_id.xy();
let screen_idx = camera.screen_to_idx(screen_pos);
diff --git a/strolle-shaders/src/di_spatial_resampling.rs b/strolle-shaders/src/di_spatial_resampling.rs
index b8696d1f..f5f16982 100644
--- a/strolle-shaders/src/di_spatial_resampling.rs
+++ b/strolle-shaders/src/di_spatial_resampling.rs
@@ -8,9 +8,9 @@ pub fn pick(
lights: &[Light],
#[spirv(descriptor_set = 1, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 1, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 3, storage_buffer)]
- reservoirs: &[Vec4],
+ reservoirs: &[DiReservoirData],
#[spirv(descriptor_set = 1, binding = 4)] buf_d0: TexRgba32,
#[spirv(descriptor_set = 1, binding = 5)] buf_d1: TexRgba32,
) {
@@ -214,9 +214,9 @@ pub fn sample(
#[spirv(push_constant)] params: &PassParams,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1, storage_buffer)]
- in_reservoirs: &[Vec4],
+ in_reservoirs: &[DiReservoirData],
#[spirv(descriptor_set = 0, binding = 2, storage_buffer)]
- out_reservoirs: &mut [Vec4],
+ out_reservoirs: &mut [DiReservoirData],
#[spirv(descriptor_set = 0, binding = 3)] buf_d2: TexRgba32,
) {
let global_id = global_id.xy();
diff --git a/strolle-shaders/src/di_temporal_resampling.rs b/strolle-shaders/src/di_temporal_resampling.rs
index 92fdbc02..fc7bce6a 100644
--- a/strolle-shaders/src/di_temporal_resampling.rs
+++ b/strolle-shaders/src/di_temporal_resampling.rs
@@ -10,13 +10,13 @@ pub fn main(
#[spirv(descriptor_set = 1, binding = 1, uniform)] prev_camera: &Camera,
#[spirv(descriptor_set = 1, binding = 2)] reprojection_map: TexRgba32,
#[spirv(descriptor_set = 1, binding = 3)] curr_prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 4)] curr_prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 4)] curr_prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 5)] prev_prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 6)] prev_prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 6)] prev_prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 7, storage_buffer)]
- prev_reservoirs: &[Vec4],
+ prev_reservoirs: &[DiReservoirData],
#[spirv(descriptor_set = 1, binding = 8, storage_buffer)]
- curr_reservoirs: &mut [Vec4],
+ curr_reservoirs: &mut [DiReservoirData],
) {
let lhs_pos = global_id.xy();
let lhs_idx = curr_camera.screen_to_idx(lhs_pos);
diff --git a/strolle-shaders/src/frame_composition.rs b/strolle-shaders/src/frame_composition.rs
index 84507fe6..e746f00c 100644
--- a/strolle-shaders/src/frame_composition.rs
+++ b/strolle-shaders/src/frame_composition.rs
@@ -20,7 +20,7 @@ pub fn fs(
#[spirv(frag_coord)] pos: Vec4,
#[spirv(push_constant)] params: &FrameCompositionPassParams,
#[spirv(descriptor_set = 0, binding = 0)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 2)] di_diff_colors: TexRgba32,
#[spirv(descriptor_set = 0, binding = 3)] di_spec_colors: TexRgba32,
#[spirv(descriptor_set = 0, binding = 4)] gi_diff_colors: TexRgba32,
diff --git a/strolle-shaders/src/frame_denoising.rs b/strolle-shaders/src/frame_denoising.rs
index be37711e..b6f16c40 100644
--- a/strolle-shaders/src/frame_denoising.rs
+++ b/strolle-shaders/src/frame_denoising.rs
@@ -4,7 +4,7 @@ use strolle_gpu::prelude::*;
pub fn reproject(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
- #[spirv(descriptor_set = 0, binding = 1)] prim_surface_map: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
#[spirv(descriptor_set = 0, binding = 2)] reprojection_map: TexRgba32,
#[spirv(descriptor_set = 1, binding = 0)] prev_colors: TexRgba32,
#[spirv(descriptor_set = 1, binding = 1)] prev_moments: TexRgba32,
@@ -13,7 +13,7 @@ pub fn reproject(
#[spirv(descriptor_set = 1, binding = 4)] moments: TexRgba32,
) {
let screen_pos = global_id.xy();
- let prim_surface_map = SurfaceMap::new(prim_surface_map);
+ let prim_surface_map = SurfaceMap::new(prim_gbuffer_d0);
let reprojection_map = ReprojectionMap::new(reprojection_map);
if !camera.contains(screen_pos) {
@@ -81,7 +81,7 @@ pub fn reproject(
pub fn estimate_variance(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
- #[spirv(descriptor_set = 0, binding = 1)] prim_surface_map: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
#[spirv(descriptor_set = 1, binding = 0)] di_colors: TexRgba32,
#[spirv(descriptor_set = 1, binding = 1)] di_moments: TexRgba32,
#[spirv(descriptor_set = 1, binding = 2)] di_output: TexRgba32,
@@ -90,7 +90,7 @@ pub fn estimate_variance(
#[spirv(descriptor_set = 2, binding = 2)] gi_output: TexRgba32,
) {
let screen_pos = global_id.xy();
- let prim_surface_map = SurfaceMap::new(prim_surface_map);
+ let prim_surface_map = SurfaceMap::new(prim_gbuffer_d0);
if !camera.contains(screen_pos) {
return;
@@ -222,7 +222,7 @@ pub fn wavelet(
#[spirv(push_constant)] params: &FrameDenoisingWaveletPassParams,
#[spirv(descriptor_set = 0, binding = 0)] blue_noise_tex: TexRgba8,
#[spirv(descriptor_set = 0, binding = 1, uniform)] camera: &Camera,
- #[spirv(descriptor_set = 0, binding = 2)] prim_surface_map: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d0: TexRgba32,
#[spirv(descriptor_set = 1, binding = 0)] di_input: TexRgba32,
#[spirv(descriptor_set = 1, binding = 1)] di_output: TexRgba32,
#[spirv(descriptor_set = 2, binding = 0)] gi_input: TexRgba32,
@@ -230,7 +230,7 @@ pub fn wavelet(
) {
let screen_pos = global_id.xy();
let bnoise = BlueNoise::new(blue_noise_tex, screen_pos, params.frame);
- let prim_surface_map = SurfaceMap::new(prim_surface_map);
+ let prim_surface_map = SurfaceMap::new(prim_gbuffer_d0);
if !camera.contains(screen_pos) {
return;
diff --git a/strolle-shaders/src/frame_reprojection.rs b/strolle-shaders/src/frame_reprojection.rs
index 4eecaf44..84e1b286 100644
--- a/strolle-shaders/src/frame_reprojection.rs
+++ b/strolle-shaders/src/frame_reprojection.rs
@@ -8,14 +8,14 @@ pub fn main(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1, uniform)] prev_camera: &Camera,
- #[spirv(descriptor_set = 0, binding = 2)] prim_surface_map: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 3)] prev_prim_surface_map: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 4)] velocity_map: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d0: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 3)] prev_prim_gbuffer_d0: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 4)] velocity_map: TexRgba16,
#[spirv(descriptor_set = 0, binding = 5)] reprojection_map: TexRgba32,
) {
let screen_pos = global_id.xy();
- let prim_surface_map = SurfaceMap::new(prim_surface_map);
- let prev_prim_surface_map = SurfaceMap::new(prev_prim_surface_map);
+ let prim_surface_map = SurfaceMap::new(prim_gbuffer_d0);
+ let prev_prim_surface_map = SurfaceMap::new(prev_prim_gbuffer_d0);
let reprojection_map = ReprojectionMap::new(reprojection_map);
if !camera.contains(screen_pos) {
diff --git a/strolle-shaders/src/gi_preview_resampling.rs b/strolle-shaders/src/gi_preview_resampling.rs
index a5125d5d..74e3005c 100644
--- a/strolle-shaders/src/gi_preview_resampling.rs
+++ b/strolle-shaders/src/gi_preview_resampling.rs
@@ -6,19 +6,18 @@ pub fn main(
#[spirv(push_constant)] params: &GiPreviewResamplingPass,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 3)] prim_surface_map: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 4, storage_buffer)]
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba16,
+ #[spirv(descriptor_set = 0, binding = 3, storage_buffer)]
in_reservoirs_a: &[Vec4],
- #[spirv(descriptor_set = 0, binding = 5, storage_buffer)]
+ #[spirv(descriptor_set = 0, binding = 4, storage_buffer)]
in_reservoirs_b: &[Vec4],
- #[spirv(descriptor_set = 0, binding = 6, storage_buffer)]
+ #[spirv(descriptor_set = 0, binding = 5, storage_buffer)]
out_reservoirs: &mut [Vec4],
) {
let center_pos = global_id.xy();
let center_idx = camera.screen_to_idx(center_pos);
let mut wnoise = WhiteNoise::new(params.seed, center_pos);
- let prim_surface_map = SurfaceMap::new(prim_surface_map);
+ let prim_surface_map = SurfaceMap::new(prim_gbuffer_d0);
if !camera.contains(center_pos) {
return;
diff --git a/strolle-shaders/src/gi_reprojection.rs b/strolle-shaders/src/gi_reprojection.rs
index 999aa5f1..711b4a1a 100644
--- a/strolle-shaders/src/gi_reprojection.rs
+++ b/strolle-shaders/src/gi_reprojection.rs
@@ -5,7 +5,7 @@ pub fn main(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 3)] reprojection_map: TexRgba32,
#[spirv(descriptor_set = 0, binding = 4, storage_buffer)]
in_reservoirs: &[Vec4],
diff --git a/strolle-shaders/src/gi_resolving.rs b/strolle-shaders/src/gi_resolving.rs
index 63d678a8..62e14a37 100644
--- a/strolle-shaders/src/gi_resolving.rs
+++ b/strolle-shaders/src/gi_resolving.rs
@@ -6,7 +6,7 @@ pub fn main(
#[spirv(push_constant)] params: &GiResolvingPassParams,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 3, storage_buffer)]
in_reservoirs_a: &[Vec4],
#[spirv(descriptor_set = 0, binding = 4, storage_buffer)]
diff --git a/strolle-shaders/src/gi_sampling_a.rs b/strolle-shaders/src/gi_sampling_a.rs
index 766b05f6..b0bc7d6c 100644
--- a/strolle-shaders/src/gi_sampling_a.rs
+++ b/strolle-shaders/src/gi_sampling_a.rs
@@ -15,7 +15,7 @@ pub fn main(
#[spirv(descriptor_set = 0, binding = 4)] atlas_sampler: &Sampler,
#[spirv(descriptor_set = 1, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 1, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 3)] gi_d0: TexRgba32,
#[spirv(descriptor_set = 1, binding = 4)] gi_d1: TexRgba32,
#[spirv(descriptor_set = 1, binding = 5)] gi_d2: TexRgba32,
diff --git a/strolle-shaders/src/gi_sampling_b.rs b/strolle-shaders/src/gi_sampling_b.rs
index 6a5a1043..91034df0 100644
--- a/strolle-shaders/src/gi_sampling_b.rs
+++ b/strolle-shaders/src/gi_sampling_b.rs
@@ -25,7 +25,7 @@ pub fn main(
#[spirv(descriptor_set = 1, binding = 4)]
atmosphere_sky_lut_sampler: &Sampler,
#[spirv(descriptor_set = 1, binding = 5)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 1, binding = 6)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 1, binding = 6)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 1, binding = 7)] gi_d0: TexRgba32,
#[spirv(descriptor_set = 1, binding = 8)] gi_d1: TexRgba32,
#[spirv(descriptor_set = 1, binding = 9)] gi_d2: TexRgba32,
@@ -197,7 +197,7 @@ pub fn main(
if gi_hit.is_some() {
radiance *= gi_hit.gbuffer.base_color.xyz() / PI;
- radiance += gi_hit.gbuffer.emissive;
+ radiance += gi_hit.gbuffer.emissive * 60.0;//Emissive strength should be parameterised somehow.
}
// -------------------------------------------------------------------------
diff --git a/strolle-shaders/src/gi_spatial_resampling.rs b/strolle-shaders/src/gi_spatial_resampling.rs
index 1258f634..8758e438 100644
--- a/strolle-shaders/src/gi_spatial_resampling.rs
+++ b/strolle-shaders/src/gi_spatial_resampling.rs
@@ -6,7 +6,7 @@ pub fn pick(
#[spirv(push_constant)] params: &PassParams,
#[spirv(descriptor_set = 0, binding = 0, uniform)] camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1)] prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 2)] prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 3, storage_buffer)]
reservoirs: &[Vec4],
#[spirv(descriptor_set = 0, binding = 4)] buf_d0: TexRgba32,
diff --git a/strolle-shaders/src/gi_temporal_resampling.rs b/strolle-shaders/src/gi_temporal_resampling.rs
index bfdbed74..9e60b24b 100644
--- a/strolle-shaders/src/gi_temporal_resampling.rs
+++ b/strolle-shaders/src/gi_temporal_resampling.rs
@@ -7,9 +7,9 @@ pub fn main(
#[spirv(descriptor_set = 0, binding = 0, uniform)] curr_camera: &Camera,
#[spirv(descriptor_set = 0, binding = 1, uniform)] prev_camera: &Camera,
#[spirv(descriptor_set = 0, binding = 2)] curr_prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 3)] curr_prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 3)] curr_prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 4)] prev_prim_gbuffer_d0: TexRgba32,
- #[spirv(descriptor_set = 0, binding = 5)] prev_prim_gbuffer_d1: TexRgba32,
+ #[spirv(descriptor_set = 0, binding = 5)] prev_prim_gbuffer_d1: TexRgba16,
#[spirv(descriptor_set = 0, binding = 6)] reprojection_map: TexRgba32,
#[spirv(descriptor_set = 0, binding = 7, storage_buffer)]
prev_reservoirs: &[Vec4],
diff --git a/strolle-shaders/src/prim_raster.rs b/strolle-shaders/src/prim_raster.rs
index af94e2e0..ae2adb83 100644
--- a/strolle-shaders/src/prim_raster.rs
+++ b/strolle-shaders/src/prim_raster.rs
@@ -59,7 +59,6 @@ pub fn fs(
// Outputs
out_prim_gbuffer_d0: &mut Vec4,
out_prim_gbuffer_d1: &mut Vec4,
- out_surface: &mut Vec4,
out_velocity: &mut Vec4,
) {
let material = MaterialsView::new(materials)
@@ -105,12 +104,6 @@ pub fn fs(
// -------------------------------------------------------------------------
- *out_surface = Normal::encode(normal)
- .extend(depth)
- .extend(material.roughness);
-
- // -------------------------------------------------------------------------
-
*out_velocity = {
let velocity = camera.clip_to_screen(curr_vertex)
- prev_camera.clip_to_screen(prev_vertex);
diff --git a/strolle/Cargo.toml b/strolle/Cargo.toml
index a13406ee..6e301da6 100644
--- a/strolle/Cargo.toml
+++ b/strolle/Cargo.toml
@@ -12,14 +12,14 @@ strolle-shaders = { path = "../strolle-shaders" }
bytemuck = "1.13.1"
derivative = "2.2.0"
fxhash = "0.2.1"
-glam = "0.24"
+glam = "0.27.0"
guillotiere = "0.6.2"
humantime = { version = "2.1.0", optional = true }
image = { version = "0.24.6", default-features = false, features = ["png"] }
log = "0.4.18"
rand = "0.8.5"
-spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu" }
-wgpu = { version = "0.17.2", features = ["spirv"] }
+spirv-std = { git = "https://github.com/glasspangolin/rust-gpu.git" }
+wgpu = { version = "0.20.1", features = ["spirv"] }
[features]
metrics = ["humantime"]
diff --git a/strolle/src/bvh/builder.rs b/strolle/src/bvh/builder.rs
index 94108866..fdbd70d7 100644
--- a/strolle/src/bvh/builder.rs
+++ b/strolle/src/bvh/builder.rs
@@ -4,7 +4,6 @@ use std::hash::{Hash, Hasher};
use std::thread;
use fxhash::FxHasher;
-use glam::UVec3;
use super::{
BvhNode, BvhNodeHash, BvhNodeId, BvhNodes, BvhPrimitiveId, BvhPrimitives,
@@ -86,7 +85,7 @@ fn find_splitting_plane(
let centroid_bb: BoundingBox = primitives
.iter()
- .map(|primitive| primitive.center)
+ .map(|primitive| -> glam::Vec3 {primitive.center})
.collect();
let mut bins = [[Bin::default(); BINS]; 3];
@@ -94,7 +93,7 @@ fn find_splitting_plane(
for primitive in primitives {
let bin_id = scale * (primitive.center - centroid_bb.min());
- let bin_id = bin_id.as_uvec3().min(UVec3::splat((BINS as u32) - 1));
+ let bin_id = bin_id.as_uvec3().min(glam::UVec3::splat((BINS as u32) - 1));
let bin_idx = bin_id.x as usize;
let bin_idy = bin_id.y as usize;
let bin_idz = bin_id.z as usize;
@@ -165,8 +164,8 @@ fn find_splitting_plane(
if is_current_bin_better {
let split_by = Axis::from(axis);
- let split_at = centroid_bb.min()[split_by]
- + scale[split_by] * ((i + 1) as f32);
+ let split_at = centroid_bb.min()[split_by as usize]
+ + scale[split_by as usize] * ((i + 1) as f32);
best = Some(SplittingPlane {
split_by,
@@ -211,7 +210,7 @@ fn split(
while left_prim_idx <= right_prim_idx {
let primitive = primitives_data[left_prim_idx as usize];
- if primitive.center[plane.split_by] < plane.split_at {
+ if primitive.center[plane.split_by as usize] < plane.split_at {
left_prim_idx += 1;
left_bounds += primitive.bounds;
diff --git a/strolle/src/bvh/serializer.rs b/strolle/src/bvh/serializer.rs
index 0203525d..0592157c 100644
--- a/strolle/src/bvh/serializer.rs
+++ b/strolle/src/bvh/serializer.rs
@@ -8,7 +8,7 @@ pub fn run(
materials: &Materials
,
nodes: &BvhNodes,
primitives: &BvhPrimitives,
- buffer: &mut Vec,
+ buffer: &mut Vec,
) where
P: Params,
{
@@ -21,7 +21,7 @@ fn serialize(
materials: &Materials
,
nodes: &BvhNodes,
primitives: &BvhPrimitives,
- buffer: &mut Vec,
+ buffer: &mut Vec,
id: BvhNodeId,
) -> u32
where
diff --git a/strolle/src/camera.rs b/strolle/src/camera.rs
index ea63e852..734854f0 100644
--- a/strolle/src/camera.rs
+++ b/strolle/src/camera.rs
@@ -1,9 +1,10 @@
use std::fmt;
use log::info;
-use spirv_std::glam::{uvec2, Mat4, UVec2, Vec3};
+use glam::{uvec2, Mat4, UVec2, Vec3};
use crate::gpu;
+use crate::utils::ToGpu;
#[derive(Clone, Debug, Default)]
pub struct Camera {
@@ -49,19 +50,19 @@ impl Camera {
pub(crate) fn serialize(&self) -> gpu::Camera {
gpu::Camera {
- projection_view: self.projection * self.transform.inverse(),
- ndc_to_world: self.transform * self.projection.inverse(),
- origin: self
+ projection_view: (self.projection * self.transform.inverse()).to_gpu(),
+ ndc_to_world: (self.transform * self.projection.inverse()).to_gpu(),
+ origin: (self
.transform
.to_scale_rotation_translation()
.2
- .extend(Default::default()),
- screen: self
+ .extend(Default::default())).to_gpu(),
+ screen: (self
.viewport
.size
.as_vec2()
.extend(Default::default())
- .extend(Default::default()),
+ .extend(Default::default())).to_gpu(),
}
}
}
diff --git a/strolle/src/camera_controller/buffers.rs b/strolle/src/camera_controller/buffers.rs
index 334278e0..b801df30 100644
--- a/strolle/src/camera_controller/buffers.rs
+++ b/strolle/src/camera_controller/buffers.rs
@@ -1,8 +1,9 @@
use log::debug;
-
+use strolle_gpu::DiReservoirData;
use crate::{
gpu, Camera, DoubleBuffered, MappedUniformBuffer, StorageBuffer, Texture,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct CameraBuffers {
@@ -16,7 +17,6 @@ pub struct CameraBuffers {
pub prim_depth: Texture,
pub prim_gbuffer_d0: DoubleBuffered,
pub prim_gbuffer_d1: DoubleBuffered,
- pub prim_surface_map: DoubleBuffered,
pub reprojection_map: Texture,
pub velocity_map: Texture,
@@ -99,7 +99,7 @@ impl CameraBuffers {
// ---------------------------------------------------------------------
let prim_depth = Texture::builder("prim_depth")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Depth32Float)
.with_usage(wgpu::TextureUsages::RENDER_ATTACHMENT)
.build(device);
@@ -107,7 +107,7 @@ impl CameraBuffers {
let prim_gbuffer_d0 = DoubleBuffered::::new(
device,
Texture::builder("prim_gbuffer_d0")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.with_usage(wgpu::TextureUsages::RENDER_ATTACHMENT),
@@ -116,17 +116,8 @@ impl CameraBuffers {
let prim_gbuffer_d1 = DoubleBuffered::::new(
device,
Texture::builder("prim_gbuffer_d1")
- .with_size(camera.viewport.size)
- .with_format(wgpu::TextureFormat::Rgba32Float)
- .with_usage(wgpu::TextureUsages::STORAGE_BINDING)
- .with_usage(wgpu::TextureUsages::RENDER_ATTACHMENT),
- );
-
- let prim_surface_map = DoubleBuffered::::new(
- device,
- Texture::builder("prim_surface_map")
- .with_size(camera.viewport.size)
- .with_format(wgpu::TextureFormat::Rgba32Float)
+ .with_size(camera.viewport.size.to_gpu())
+ .with_format(wgpu::TextureFormat::Rgba16Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.with_usage(wgpu::TextureUsages::RENDER_ATTACHMENT),
);
@@ -134,44 +125,46 @@ impl CameraBuffers {
// ---------------------------------------------------------------------
let reprojection_map = Texture::builder("reprojection_map")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let velocity_map = Texture::builder("velocity_map")
- .with_size(camera.viewport.size)
- .with_format(wgpu::TextureFormat::Rgba32Float)
+ .with_size(camera.viewport.size.to_gpu())
+ .with_format(wgpu::TextureFormat::Rgba16Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.with_usage(wgpu::TextureUsages::RENDER_ATTACHMENT)
.build(device);
// ---------------------------------------------------------------------
+ let element_size = std::mem::size_of::();
+ let element_size_round = (element_size as f32 / 32.0).ceil() as usize * 32;
let di_reservoirs = [0, 1, 2].map(|idx| {
StorageBuffer::new(
device,
format!("di_reservoir_{}", idx),
- viewport_buffer_size(2 * 4 * 4),
+ viewport_buffer_size(element_size_round),
)
});
// ---
let di_diff_samples = Texture::builder("di_diff_samples")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let di_diff_prev_colors = Texture::builder("di_diff_prev_colors")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let di_diff_curr_colors = Texture::builder("di_diff_curr_colors")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -179,13 +172,13 @@ impl CameraBuffers {
let di_diff_moments = DoubleBuffered::::new(
device,
Texture::builder("di_diff_moments")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING),
);
let di_diff_stash = Texture::builder("di_diff_stash")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -193,7 +186,7 @@ impl CameraBuffers {
// ---
let di_spec_samples = Texture::builder("di_spec_samples")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -201,19 +194,19 @@ impl CameraBuffers {
// ---------------------------------------------------------------------
let gi_d0 = Texture::builder("gi_d0")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let gi_d1 = Texture::builder("gi_d1")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let gi_d2 = Texture::builder("gi_d2")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -229,19 +222,19 @@ impl CameraBuffers {
// ---
let gi_diff_samples = Texture::builder("gi_diff_samples")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let gi_diff_prev_colors = Texture::builder("gi_diff_prev_colors")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
let gi_diff_curr_colors = Texture::builder("gi_diff_curr_colors")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -249,13 +242,13 @@ impl CameraBuffers {
let gi_diff_moments = DoubleBuffered::::new(
device,
Texture::builder("gi_diff_moments")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING),
);
let gi_diff_stash = Texture::builder("gi_diff_stash")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -263,7 +256,7 @@ impl CameraBuffers {
// ---
let gi_spec_samples = Texture::builder("gi_spec_samples")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -286,7 +279,7 @@ impl CameraBuffers {
// TODO initialize lazily
let ref_colors = Texture::builder("ref_colors")
- .with_size(camera.viewport.size)
+ .with_size(camera.viewport.size.to_gpu())
.with_format(wgpu::TextureFormat::Rgba32Float)
.with_usage(wgpu::TextureUsages::STORAGE_BINDING)
.build(device);
@@ -304,7 +297,6 @@ impl CameraBuffers {
prim_depth,
prim_gbuffer_d0,
prim_gbuffer_d1,
- prim_surface_map,
reprojection_map,
velocity_map,
diff --git a/strolle/src/camera_controller/pass.rs b/strolle/src/camera_controller/pass.rs
index 6cd288b2..9b50c2e4 100644
--- a/strolle/src/camera_controller/pass.rs
+++ b/strolle/src/camera_controller/pass.rs
@@ -42,6 +42,7 @@ where
let mut pass =
encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label: Some(&label),
+ timestamp_writes: None,
});
pass.set_pipeline(&self.pipeline);
@@ -136,7 +137,8 @@ where
label: Some(&pipeline_label),
layout: Some(&pipeline_layout),
module,
- entry_point,
+ entry_point: entry_point,
+ compilation_options: Default::default(),
});
CameraComputePass {
diff --git a/strolle/src/camera_controller/passes/bvh_heatmap.rs b/strolle/src/camera_controller/passes/bvh_heatmap.rs
index bfe0885d..efd24d0c 100644
--- a/strolle/src/camera_controller/passes/bvh_heatmap.rs
+++ b/strolle/src/camera_controller/passes/bvh_heatmap.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct BvhHeatmapPass {
@@ -41,6 +42,6 @@ impl BvhHeatmapPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, ());
+ self.pass.run(camera, encoder, size.to_gpu(), ());
}
}
diff --git a/strolle/src/camera_controller/passes/di_resolving.rs b/strolle/src/camera_controller/passes/di_resolving.rs
index a76699b0..d4c60883 100644
--- a/strolle/src/camera_controller/passes/di_resolving.rs
+++ b/strolle/src/camera_controller/passes/di_resolving.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct DiResolvingPass {
@@ -50,6 +51,6 @@ impl DiResolvingPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, camera.pass_params());
+ self.pass.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/di_sampling.rs b/strolle/src/camera_controller/passes/di_sampling.rs
index 60644025..51e9e82a 100644
--- a/strolle/src/camera_controller/passes/di_sampling.rs
+++ b/strolle/src/camera_controller/passes/di_sampling.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct DiSamplingPass {
@@ -46,6 +47,6 @@ impl DiSamplingPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, camera.pass_params());
+ self.pass.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/di_spatial_resampling.rs b/strolle/src/camera_controller/passes/di_spatial_resampling.rs
index 0eff3d27..beed2959 100644
--- a/strolle/src/camera_controller/passes/di_spatial_resampling.rs
+++ b/strolle/src/camera_controller/passes/di_spatial_resampling.rs
@@ -3,6 +3,7 @@ use glam::uvec2;
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct DiSpatialResamplingPass {
@@ -81,21 +82,21 @@ impl DiSpatialResamplingPass {
self.pick_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8 / uvec2(2, 1),
+ ((camera.camera.viewport.size + 7) / 8 / uvec2(2, 1)).to_gpu(),
camera.pass_params(),
);
self.trace_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8,
+ ((camera.camera.viewport.size + 7) / 8).to_gpu(),
camera.pass_params(),
);
self.sample_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8 / uvec2(2, 1),
+ ((camera.camera.viewport.size + 7) / 8 / uvec2(2, 1)).to_gpu(),
camera.pass_params(),
);
}
diff --git a/strolle/src/camera_controller/passes/di_temporal_resampling.rs b/strolle/src/camera_controller/passes/di_temporal_resampling.rs
index 940e744a..108d121a 100644
--- a/strolle/src/camera_controller/passes/di_temporal_resampling.rs
+++ b/strolle/src/camera_controller/passes/di_temporal_resampling.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct DiTemporalResamplingPass {
@@ -43,6 +44,6 @@ impl DiTemporalResamplingPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, camera.pass_params());
+ self.pass.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/frame_composition.rs b/strolle/src/camera_controller/passes/frame_composition.rs
index 3c36b88a..b8e07bb3 100644
--- a/strolle/src/camera_controller/passes/frame_composition.rs
+++ b/strolle/src/camera_controller/passes/frame_composition.rs
@@ -77,6 +77,7 @@ impl FrameCompositionPass {
vertex: wgpu::VertexState {
module: &engine.shaders.frame_composition_vs.0,
entry_point: engine.shaders.frame_composition_vs.1,
+ compilation_options: Default::default(),
buffers: &[],
},
primitive: wgpu::PrimitiveState::default(),
@@ -85,6 +86,7 @@ impl FrameCompositionPass {
fragment: Some(wgpu::FragmentState {
module: &engine.shaders.frame_composition_fs.0,
entry_point: engine.shaders.frame_composition_fs.1,
+ compilation_options: Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: camera.viewport.format,
blend: Some(wgpu::BlendState::REPLACE),
@@ -112,10 +114,12 @@ impl FrameCompositionPass {
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
- store: true,
+ store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
+ timestamp_writes: None,
+ occlusion_query_set: None,
});
let params = gpu::FrameCompositionPassParams {
diff --git a/strolle/src/camera_controller/passes/frame_denoising.rs b/strolle/src/camera_controller/passes/frame_denoising.rs
index 557c4262..2c1410bf 100644
--- a/strolle/src/camera_controller/passes/frame_denoising.rs
+++ b/strolle/src/camera_controller/passes/frame_denoising.rs
@@ -3,6 +3,7 @@ use crate::{
gpu, Camera, CameraBuffers, CameraComputePass, CameraController, Engine,
Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct FrameDenoisingPass {
@@ -26,7 +27,7 @@ impl FrameDenoisingPass {
CameraComputePass::builder("frame_denoising_reproject_di")
.bind([
&buffers.curr_camera.bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
+ &buffers.prim_gbuffer_d0.curr().bind_readable(),
&buffers.reprojection_map.bind_readable(),
])
.bind([
@@ -42,7 +43,7 @@ impl FrameDenoisingPass {
CameraComputePass::builder("frame_denoising_reproject_gi")
.bind([
&buffers.curr_camera.bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
+ &buffers.prim_gbuffer_d0.curr().bind_readable(),
&buffers.reprojection_map.bind_readable(),
])
.bind([
@@ -58,7 +59,7 @@ impl FrameDenoisingPass {
CameraComputePass::builder("frame_denoising_estimate_variance")
.bind([
&buffers.curr_camera.bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
+ &buffers.prim_gbuffer_d0.curr().bind_readable(),
])
.bind([
&buffers.di_diff_curr_colors.bind_readable(),
@@ -119,7 +120,7 @@ impl FrameDenoisingPass {
.bind([
&engine.noise.bind_blue_noise(),
&buffers.curr_camera.bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
+ &buffers.prim_gbuffer_d0.curr().bind_readable(),
])
.bind([
&wavelet.di.0.bind_readable(),
@@ -155,21 +156,21 @@ impl FrameDenoisingPass {
self.reproject_passes[0].run(
camera,
encoder,
- size,
+ size.to_gpu(),
camera.pass_params(),
);
self.reproject_passes[1].run(
camera,
encoder,
- size,
+ size.to_gpu(),
camera.pass_params(),
);
self.estimate_variance_pass.run(
camera,
encoder,
- size,
+ size.to_gpu(),
camera.pass_params(),
);
@@ -179,7 +180,7 @@ impl FrameDenoisingPass {
pass.run(
camera,
encoder,
- size,
+ size.to_gpu(),
gpu::FrameDenoisingWaveletPassParams {
frame: camera.frame,
stride: 2u32.pow(nth),
diff --git a/strolle/src/camera_controller/passes/frame_reprojection.rs b/strolle/src/camera_controller/passes/frame_reprojection.rs
index 50f0c369..5f0c44bd 100644
--- a/strolle/src/camera_controller/passes/frame_reprojection.rs
+++ b/strolle/src/camera_controller/passes/frame_reprojection.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct FrameReprojectionPass {
@@ -21,8 +22,8 @@ impl FrameReprojectionPass {
.bind([
&buffers.curr_camera.bind_readable(),
&buffers.prev_camera.bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
- &buffers.prim_surface_map.prev().bind_readable(),
+ &buffers.prim_gbuffer_d0.curr().bind_readable(),
+ &buffers.prim_gbuffer_d0.prev().bind_readable(),
&buffers.velocity_map.bind_readable(),
&buffers.reprojection_map.bind_writable(),
])
@@ -39,6 +40,6 @@ impl FrameReprojectionPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, ());
+ self.pass.run(camera, encoder, size.to_gpu(), ());
}
}
diff --git a/strolle/src/camera_controller/passes/gi_preview_resampling.rs b/strolle/src/camera_controller/passes/gi_preview_resampling.rs
index 928523fd..1525a4e4 100644
--- a/strolle/src/camera_controller/passes/gi_preview_resampling.rs
+++ b/strolle/src/camera_controller/passes/gi_preview_resampling.rs
@@ -2,6 +2,7 @@ use crate::{
gpu, Camera, CameraBuffers, CameraComputePass, CameraController, Engine,
Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiPreviewResamplingPass {
@@ -23,7 +24,6 @@ impl GiPreviewResamplingPass {
&buffers.curr_camera.bind_readable(),
&buffers.prim_gbuffer_d0.curr().bind_readable(),
&buffers.prim_gbuffer_d1.curr().bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
&buffers.gi_reservoirs[1].bind_readable(),
&buffers.gi_reservoirs[2].bind_readable(),
&buffers.gi_reservoirs[3].bind_writable(),
@@ -35,7 +35,6 @@ impl GiPreviewResamplingPass {
&buffers.curr_camera.bind_readable(),
&buffers.prim_gbuffer_d0.curr().bind_readable(),
&buffers.prim_gbuffer_d1.curr().bind_readable(),
- &buffers.prim_surface_map.curr().bind_readable(),
&buffers.gi_reservoirs[1].bind_readable(),
&buffers.gi_reservoirs[3].bind_readable(),
&buffers.gi_reservoirs[0].bind_writable(),
@@ -63,7 +62,7 @@ impl GiPreviewResamplingPass {
pass.run(
camera,
encoder,
- size,
+ size.to_gpu(),
gpu::GiPreviewResamplingPass {
seed: params.seed,
frame: params.frame,
diff --git a/strolle/src/camera_controller/passes/gi_reprojection.rs b/strolle/src/camera_controller/passes/gi_reprojection.rs
index bb14458c..f02c1f9f 100644
--- a/strolle/src/camera_controller/passes/gi_reprojection.rs
+++ b/strolle/src/camera_controller/passes/gi_reprojection.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiReprojectionPass {
@@ -39,6 +40,6 @@ impl GiReprojectionPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, camera.pass_params());
+ self.pass.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/gi_resolving.rs b/strolle/src/camera_controller/passes/gi_resolving.rs
index 156176a4..2dceb26b 100644
--- a/strolle/src/camera_controller/passes/gi_resolving.rs
+++ b/strolle/src/camera_controller/passes/gi_resolving.rs
@@ -2,6 +2,7 @@ use crate::{
gpu, Camera, CameraBuffers, CameraComputePass, CameraController, Engine,
Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiResolvingPass {
@@ -46,7 +47,7 @@ impl GiResolvingPass {
self.pass.run(
camera,
encoder,
- size,
+ size.to_gpu(),
gpu::GiResolvingPassParams {
frame: camera.frame,
source,
diff --git a/strolle/src/camera_controller/passes/gi_sampling.rs b/strolle/src/camera_controller/passes/gi_sampling.rs
index a805d39a..3179d735 100644
--- a/strolle/src/camera_controller/passes/gi_sampling.rs
+++ b/strolle/src/camera_controller/passes/gi_sampling.rs
@@ -3,6 +3,7 @@ use glam::uvec2;
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiSamplingPass {
@@ -72,7 +73,7 @@ impl GiSamplingPass {
// These passes use 8x8 warps and 2x1 checkerboard:
let size = (camera.camera.viewport.size + 7) / 8 / uvec2(2, 1);
- self.pass_a.run(camera, encoder, size, camera.pass_params());
- self.pass_b.run(camera, encoder, size, camera.pass_params());
+ self.pass_a.run(camera, encoder, size.to_gpu(), camera.pass_params());
+ self.pass_b.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/gi_spatial_resampling.rs b/strolle/src/camera_controller/passes/gi_spatial_resampling.rs
index a6c3d235..5486889d 100644
--- a/strolle/src/camera_controller/passes/gi_spatial_resampling.rs
+++ b/strolle/src/camera_controller/passes/gi_spatial_resampling.rs
@@ -3,6 +3,7 @@ use glam::uvec2;
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiSpatialResamplingPass {
@@ -74,21 +75,21 @@ impl GiSpatialResamplingPass {
self.pick_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8 / uvec2(2, 1),
+ ((camera.camera.viewport.size + 7) / 8 / uvec2(2, 1)).to_gpu(),
camera.pass_params(),
);
self.trace_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8,
+ ((camera.camera.viewport.size + 7) / 8).to_gpu(),
camera.pass_params(),
);
self.sample_pass.run(
camera,
encoder,
- (camera.camera.viewport.size + 7) / 8 / uvec2(2, 1),
+ ((camera.camera.viewport.size + 7) / 8 / uvec2(2, 1)).to_gpu(),
camera.pass_params(),
);
}
diff --git a/strolle/src/camera_controller/passes/gi_temporal_resampling.rs b/strolle/src/camera_controller/passes/gi_temporal_resampling.rs
index f8957799..4d1553ef 100644
--- a/strolle/src/camera_controller/passes/gi_temporal_resampling.rs
+++ b/strolle/src/camera_controller/passes/gi_temporal_resampling.rs
@@ -1,6 +1,7 @@
use crate::{
Camera, CameraBuffers, CameraComputePass, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct GiTemporalResamplingPass {
@@ -42,6 +43,6 @@ impl GiTemporalResamplingPass {
// This pass uses 8x8 warps:
let size = (camera.camera.viewport.size + 7) / 8;
- self.pass.run(camera, encoder, size, camera.pass_params());
+ self.pass.run(camera, encoder, size.to_gpu(), camera.pass_params());
}
}
diff --git a/strolle/src/camera_controller/passes/prim_raster.rs b/strolle/src/camera_controller/passes/prim_raster.rs
index 15a5f4c3..325dc637 100644
--- a/strolle/src/camera_controller/passes/prim_raster.rs
+++ b/strolle/src/camera_controller/passes/prim_raster.rs
@@ -7,6 +7,7 @@ use log::debug;
use crate::{
gpu, BindGroup, Camera, CameraBuffers, CameraController, Engine, Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct PrimRasterPass {
@@ -57,6 +58,7 @@ impl PrimRasterPass {
vertex: wgpu::VertexState {
module: &engine.shaders.prim_raster_vs.0,
entry_point: engine.shaders.prim_raster_vs.1,
+ compilation_options: Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: (3 * 4 * mem::size_of::()) as _,
step_mode: wgpu::VertexStepMode::Vertex,
@@ -102,6 +104,7 @@ impl PrimRasterPass {
fragment: Some(wgpu::FragmentState {
module: &engine.shaders.prim_raster_fs.0,
entry_point: engine.shaders.prim_raster_fs.1,
+ compilation_options: Default::default(),
targets: &[
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba32Float,
@@ -109,17 +112,12 @@ impl PrimRasterPass {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
- format: wgpu::TextureFormat::Rgba32Float,
+ format: wgpu::TextureFormat::Rgba16Float,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
- format: wgpu::TextureFormat::Rgba32Float,
- blend: Some(wgpu::BlendState::REPLACE),
- write_mask: wgpu::ColorWrites::ALL,
- }),
- Some(wgpu::ColorTargetState {
- format: wgpu::TextureFormat::Rgba32Float,
+ format: wgpu::TextureFormat::Rgba16Float,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
}),
@@ -149,7 +147,7 @@ impl PrimRasterPass {
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
- store: true,
+ store: wgpu::StoreOp::Store,
},
}),
Some(wgpu::RenderPassColorAttachment {
@@ -157,15 +155,7 @@ impl PrimRasterPass {
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
- store: true,
- },
- }),
- Some(wgpu::RenderPassColorAttachment {
- view: camera.buffers.prim_surface_map.get(alternate).view(),
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
- store: true,
+ store: wgpu::StoreOp::Store,
},
}),
Some(wgpu::RenderPassColorAttachment {
@@ -173,7 +163,7 @@ impl PrimRasterPass {
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
- store: true,
+ store: wgpu::StoreOp::Store,
},
}),
],
@@ -182,11 +172,13 @@ impl PrimRasterPass {
view: camera.buffers.prim_depth.view(),
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(0.0),
- store: true,
+ store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
},
),
+ timestamp_writes: None,
+ occlusion_query_set: None,
});
pass.set_pipeline(&self.pipeline);
@@ -204,11 +196,11 @@ impl PrimRasterPass {
let params = {
let curr_xform_inv = gpu::PrimRasterPassParams::encode_affine(
- instance.transform_inverse,
+ instance.transform_inverse.to_gpu(),
);
let prev_xform = gpu::PrimRasterPassParams::encode_affine(
- instance_entry.prev_transform,
+ instance_entry.prev_transform.to_gpu(),
);
gpu::PrimRasterPassParams {
@@ -217,7 +209,7 @@ impl PrimRasterPass {
f32::from_bits(material_id.get()),
Default::default(),
Default::default(),
- ),
+ ).to_gpu(),
curr_xform_inv_d0: curr_xform_inv[0],
curr_xform_inv_d1: curr_xform_inv[1],
curr_xform_inv_d2: curr_xform_inv[2],
diff --git a/strolle/src/camera_controller/passes/ref_shading.rs b/strolle/src/camera_controller/passes/ref_shading.rs
index 604e67f1..31402c02 100644
--- a/strolle/src/camera_controller/passes/ref_shading.rs
+++ b/strolle/src/camera_controller/passes/ref_shading.rs
@@ -4,6 +4,7 @@ use crate::{
gpu, Camera, CameraBuffers, CameraComputePass, CameraController, Engine,
Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct RefShadingPass {
@@ -58,6 +59,6 @@ impl RefShadingPass {
depth: depth as u32,
};
- self.pass.run(camera, encoder, size, params);
+ self.pass.run(camera, encoder, size.to_gpu(), params);
}
}
diff --git a/strolle/src/camera_controller/passes/ref_tracing.rs b/strolle/src/camera_controller/passes/ref_tracing.rs
index 643a1aab..f083e821 100644
--- a/strolle/src/camera_controller/passes/ref_tracing.rs
+++ b/strolle/src/camera_controller/passes/ref_tracing.rs
@@ -4,6 +4,7 @@ use crate::{
gpu, Camera, CameraBuffers, CameraComputePass, CameraController, Engine,
Params,
};
+use crate::utils::ToGpu;
#[derive(Debug)]
pub struct RefTracingPass {
@@ -52,6 +53,6 @@ impl RefTracingPass {
depth: depth as u32,
};
- self.pass.run(camera, encoder, size, params);
+ self.pass.run(camera, encoder, size.to_gpu(), params);
}
}
diff --git a/strolle/src/images.rs b/strolle/src/images.rs
index 3a685fa4..eac8b757 100644
--- a/strolle/src/images.rs
+++ b/strolle/src/images.rs
@@ -5,8 +5,9 @@ use derivative::Derivative;
use glam::{uvec2, vec4, Vec4};
use guillotiere::{size2, Allocation, AtlasAllocator};
use log::warn;
-
+use wgpu::TextureFormat;
use crate::{Bindable, Image, ImageData, Params, Texture};
+use crate::utils::ToGpu;
#[derive(Derivative)]
#[derivative(Debug)]
@@ -22,6 +23,40 @@ where
dynamic_textures: Vec<(P::ImageTexture, Allocation)>,
}
+fn convert_to_rgba8unorm_srgb(
+ data: &[u8],
+ src_format: wgpu::TextureFormat,
+ width: u32,
+ height: u32,
+) -> Vec {
+ let pixel_count = (width * height) as usize;
+ let mut converted_data = Vec::with_capacity(pixel_count * 4);
+
+ match src_format {
+ wgpu::TextureFormat::R8Unorm => {
+ for &r in data {
+ converted_data.extend_from_slice(&[r, 0, 0, 255]);
+ }
+ }
+ wgpu::TextureFormat::Rg8Unorm => {
+ for chunk in data.chunks_exact(2) {
+ let r = chunk[0];
+ let g = chunk[1];
+ converted_data.extend_from_slice(&[r, g, 0, 255]);
+ }
+ }
+ wgpu::TextureFormat::Rgba8UnormSrgb => {
+ converted_data.extend_from_slice(data);
+ }
+ _ => {
+ println!("Unhandled texture format: {:?}", src_format);
+ }
+ }
+
+ converted_data
+}
+
+
impl Images
where
P: Params,
@@ -36,7 +71,7 @@ where
));
let atlas_texture = Texture::builder("atlas")
- .with_size(uvec2(Self::ATLAS_WIDTH, Self::ATLAS_HEIGHT))
+ .with_size(uvec2(Self::ATLAS_WIDTH, Self::ATLAS_HEIGHT).to_gpu())
.with_format(wgpu::TextureFormat::Rgba8UnormSrgb)
.with_usage(wgpu::TextureUsages::TEXTURE_BINDING)
.with_usage(wgpu::TextureUsages::COPY_DST)
@@ -85,13 +120,55 @@ where
| ImageData::Texture {
is_dynamic: false, ..
}) => {
- self.atlas_changes.push(AtlasChange::Set {
- x: alloc.rectangle.min.x as u32,
- y: alloc.rectangle.min.y as u32,
- w: alloc.rectangle.width() as u32,
- h: alloc.rectangle.height() as u32,
- data,
- });
+ match &data {
+ ImageData::Raw { data } => {
+ // Convert data to atlas format (Rgba8UnormSrgb)
+ let converted_data = convert_to_rgba8unorm_srgb(
+ data,
+ item.texture_descriptor.format,
+ item.texture_descriptor.size.width,
+ item.texture_descriptor.size.height,
+ );
+
+ // Use atlas texture's format for calculations
+ let block_size = 4; // Rgba8UnormSrgb has 4 bytes per pixel
+ let unpadded_bytes_per_row =
+ item.texture_descriptor.size.width * block_size;
+ let padding = (256 - (unpadded_bytes_per_row % 256)) % 256;
+ let padded_bytes_per_row = unpadded_bytes_per_row + padding;
+
+ // Pad the converted data if necessary
+ let mut padded_data = Vec::with_capacity(
+ (padded_bytes_per_row * item.texture_descriptor.size.height) as usize,
+ );
+ if padding == 0 {
+ padded_data = converted_data;
+ } else {
+ let row_length = (unpadded_bytes_per_row) as usize;
+ for row in converted_data.chunks_exact(row_length) {
+ padded_data.extend_from_slice(row);
+ padded_data.extend(std::iter::repeat(0).take(padding as usize));
+ }
+ }
+
+ self.atlas_changes.push(AtlasChange::Set {
+ x: alloc.rectangle.min.x as u32,
+ y: alloc.rectangle.min.y as u32,
+ w: alloc.rectangle.width() as u32,
+ h: alloc.rectangle.height() as u32,
+ data: ImageData::Raw { data: padded_data },
+ });
+ }
+ ImageData::Texture { texture, .. } => {
+ self.atlas_changes.push(AtlasChange::Set {
+ x: alloc.rectangle.min.x as u32,
+ y: alloc.rectangle.min.y as u32,
+ w: alloc.rectangle.width() as u32,
+ h: alloc.rectangle.height() as u32,
+ data: data,
+ });
+ }
+ };
}
ImageData::Texture {
@@ -140,6 +217,23 @@ where
match data {
ImageData::Raw { data } => {
+ // Use atlas texture's format for calculations
+ let block_size = 4; // Rgba8UnormSrgb has 4 bytes per pixel
+ let unpadded_bytes_per_row = w * block_size;
+ let padding = (256 - (unpadded_bytes_per_row % 256)) % 256;
+ let padded_bytes_per_row = unpadded_bytes_per_row + padding;
+
+ println!(
+ "Writing texture: pos={}x{}, size={}x{}, data_len={}, bytes_per_row={}, padded_bytes_per_row={}",
+ x,
+ y,
+ w,
+ h,
+ data.len(),
+ unpadded_bytes_per_row,
+ padded_bytes_per_row
+ );
+
queue.write_texture(
wgpu::ImageCopyTexture {
texture: self.atlas_texture.tex(),
@@ -150,14 +244,10 @@ where
&data,
wgpu::ImageDataLayout {
offset: 0,
- bytes_per_row: Some(w * 4),
+ bytes_per_row: Some(padded_bytes_per_row),
rows_per_image: None,
},
- wgpu::Extent3d {
- width: w,
- height: h,
- depth_or_array_layers: 1,
- },
+ size,
);
}
diff --git a/strolle/src/lib.rs b/strolle/src/lib.rs
index 0f1bd294..e8b8a754 100644
--- a/strolle/src/lib.rs
+++ b/strolle/src/lib.rs
@@ -75,10 +75,12 @@ use std::ops::Deref;
use std::time::Instant;
use std::{env, mem};
-pub use glam;
+use glam;
use log::{info, trace};
use strolle_gpu as gpu;
+pub use crate::utils::interface::ToGpu;
+
pub(crate) use self::buffers::*;
pub(crate) use self::bvh::*;
pub use self::camera::*;
diff --git a/strolle/src/light.rs b/strolle/src/light.rs
index 6440270e..c8b470f5 100644
--- a/strolle/src/light.rs
+++ b/strolle/src/light.rs
@@ -1,6 +1,7 @@
use glam::{vec4, Vec3};
use crate::gpu;
+use crate::utils::ToGpu;
#[derive(Clone, Debug)]
pub enum Light {
@@ -53,7 +54,7 @@ impl Light {
direction,
angle,
} => {
- let direction = gpu::Normal::encode(*direction);
+ let direction = gpu::Normal::encode((*direction).to_gpu());
d0 = position.extend(*radius);
d1 = color.extend(*range);
@@ -68,9 +69,9 @@ impl Light {
}
gpu::Light {
- d0,
- d1,
- d2,
+ d0: d0.to_gpu(),
+ d1: d1.to_gpu(),
+ d2: d2.to_gpu(),
d3: Default::default(),
prev_d0: Default::default(),
prev_d1: Default::default(),
diff --git a/strolle/src/material.rs b/strolle/src/material.rs
index 1d79abda..cd012431 100644
--- a/strolle/src/material.rs
+++ b/strolle/src/material.rs
@@ -3,6 +3,7 @@ use std::fmt::Debug;
use spirv_std::glam::{vec4, Vec4};
use crate::{gpu, Images, Params};
+use crate::utils::ToGpu;
#[derive(Clone, Debug)]
pub struct Material
@@ -31,21 +32,21 @@ where
base_color: self.base_color,
base_color_texture: images
.lookup_opt(self.base_color_texture)
- .unwrap_or_default(),
+ .unwrap_or_default().to_gpu(),
emissive: self.emissive,
emissive_texture: images
.lookup_opt(self.emissive_texture)
- .unwrap_or_default(),
+ .unwrap_or_default().to_gpu(),
roughness: self.perceptual_roughness.powf(2.0),
metallic: self.metallic,
metallic_roughness_texture: images
.lookup_opt(self.metallic_roughness_texture)
- .unwrap_or_default(),
+ .unwrap_or_default().to_gpu(),
reflectance: self.reflectance,
ior: self.ior,
normal_map_texture: images
.lookup_opt(self.normal_map_texture)
- .unwrap_or_default(),
+ .unwrap_or_default().to_gpu(),
}
}
}
diff --git a/strolle/src/mesh_triangle.rs b/strolle/src/mesh_triangle.rs
index 3a5d38e7..d7e7bb59 100644
--- a/strolle/src/mesh_triangle.rs
+++ b/strolle/src/mesh_triangle.rs
@@ -1,6 +1,5 @@
-use glam::Affine3A;
-use spirv_std::glam::{Mat4, Vec2, Vec3, Vec4, Vec4Swizzles};
+use glam::{Vec2, Vec3, Vec4, Mat4, Affine3A, Vec4Swizzles};
use crate::Triangle;
#[derive(Clone, Debug, Default)]
@@ -17,17 +16,17 @@ impl MeshTriangle {
self
}
- pub fn with_normals(mut self, normals: [impl Into; 3]) -> Self {
- self.normals = normals.map(Into::into);
+ pub fn with_normals(mut self, normals: [Vec3; 3]) -> Self {
+ self.normals = normals;
self
}
- pub fn with_uvs(mut self, uvs: [impl Into; 3]) -> Self {
- self.uvs = uvs.map(Into::into);
+ pub fn with_uvs(mut self, uvs: [Vec2; 3]) -> Self {
+ self.uvs = uvs;
self
}
- pub fn with_tangents(mut self, tangents: [impl Into; 3]) -> Self {
+ pub fn with_tangents(mut self, tangents: [Vec4; 3]) -> Self {
self.tangents = tangents.map(Into::into);
self
}
@@ -49,8 +48,8 @@ impl MeshTriangle {
xform: Affine3A,
xform_inv: Affine3A,
) -> Triangle {
- let positions =
- self.positions.map(|vertex| xform.transform_point3(vertex));
+ let positions: [Vec3; 3] =
+ self.positions.map(|vertex: Vec3| -> Vec3 {xform.transform_point3(vertex)});
let normals = {
// Transforming normals requires inversing and transposing the
@@ -77,10 +76,12 @@ impl MeshTriangle {
})
};
+ let uvs = self.uvs.map(|uv| {uv});
+
Triangle {
positions,
normals,
- uvs: self.uvs,
+ uvs,
tangents,
}
}
diff --git a/strolle/src/triangle.rs b/strolle/src/triangle.rs
index 50d80dba..73694b4e 100644
--- a/strolle/src/triangle.rs
+++ b/strolle/src/triangle.rs
@@ -1,8 +1,8 @@
use glam::Vec3Swizzles;
-use spirv_std::glam::{Vec2, Vec3, Vec4};
+use glam::{Vec2, Vec3, Vec4};
use crate::gpu;
-use crate::utils::BoundingBox;
+use crate::utils::{BoundingBox, ToGpu};
#[derive(Clone, Debug)]
pub struct Triangle {
@@ -23,17 +23,17 @@ impl Triangle {
pub fn serialize(&self) -> gpu::Triangle {
gpu::Triangle {
- d0: self.positions[0].xyz().extend(self.uvs[0].x),
- d1: self.normals[0].xyz().extend(self.uvs[0].y),
- d2: self.tangents[0],
+ d0: self.positions[0].xyz().extend(self.uvs[0].x).to_gpu(),
+ d1: self.normals[0].xyz().extend(self.uvs[0].y).to_gpu(),
+ d2: self.tangents[0].to_gpu(),
- d3: self.positions[1].xyz().extend(self.uvs[1].x),
- d4: self.normals[1].xyz().extend(self.uvs[1].y),
- d5: self.tangents[1],
+ d3: self.positions[1].xyz().extend(self.uvs[1].x).to_gpu(),
+ d4: self.normals[1].xyz().extend(self.uvs[1].y).to_gpu(),
+ d5: self.tangents[1].to_gpu(),
- d6: self.positions[2].xyz().extend(self.uvs[2].x),
- d7: self.normals[2].xyz().extend(self.uvs[2].y),
- d8: self.tangents[2],
+ d6: self.positions[2].xyz().extend(self.uvs[2].x).to_gpu(),
+ d7: self.normals[2].xyz().extend(self.uvs[2].y).to_gpu(),
+ d8: self.tangents[2].to_gpu(),
}
}
}
diff --git a/strolle/src/utils.rs b/strolle/src/utils.rs
index e3c81beb..0c319b80 100644
--- a/strolle/src/utils.rs
+++ b/strolle/src/utils.rs
@@ -2,8 +2,12 @@ mod allocator;
mod axis;
mod bounding_box;
mod metrics;
+pub mod interface;
pub use self::allocator::*;
pub use self::axis::*;
pub use self::bounding_box::*;
pub use self::metrics::*;
+pub use self::interface::*;
+
+
diff --git a/strolle/src/utils/bounding_box.rs b/strolle/src/utils/bounding_box.rs
index 6ff28a9f..681f95b5 100644
--- a/strolle/src/utils/bounding_box.rs
+++ b/strolle/src/utils/bounding_box.rs
@@ -1,6 +1,6 @@
use std::ops::{Add, AddAssign};
-use spirv_std::glam::Vec3;
+use glam::Vec3;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct BoundingBox {
diff --git a/strolle/src/utils/interface.rs b/strolle/src/utils/interface.rs
new file mode 100644
index 00000000..521f1dcf
--- /dev/null
+++ b/strolle/src/utils/interface.rs
@@ -0,0 +1,58 @@
+// First, let's define helper traits for converting between CPU and GPU types
+use glam as cpu;
+use spirv_std::glam as gpu;
+
+// Helper trait for converting CPU types to GPU types
+pub trait ToGpu {
+ fn to_gpu(&self) -> T;
+}
+
+
+impl ToGpu for cpu::Affine3A {
+ fn to_gpu(&self) -> gpu::Affine3A {
+ gpu::Affine3A::from_cols_array(&self.to_cols_array())
+ }
+}
+
+impl ToGpu for cpu::Mat4 {
+ fn to_gpu(&self) -> gpu::Mat4 {
+ gpu::Mat4::from_cols_array(&self.to_cols_array())
+ }
+}
+
+impl ToGpu for cpu::Vec4 {
+ fn to_gpu(&self) -> gpu::Vec4 {
+ gpu::Vec4::new(self.x, self.y, self.z, self.w)
+ }
+}
+
+impl ToGpu for cpu::Vec3 {
+ fn to_gpu(&self) -> gpu::Vec3 {
+ gpu::Vec3::new(self.x, self.y, self.z)
+ }
+}
+
+impl ToGpu for cpu::Vec2 {
+ fn to_gpu(&self) -> gpu::Vec2 {
+ gpu::Vec2::new(self.x, self.y)
+ }
+}
+
+
+impl ToGpu for cpu::UVec2 {
+ fn to_gpu(&self) -> gpu::UVec2 {
+ gpu::UVec2::new(self.x, self.y)
+ }
+}
+
+impl ToGpu for cpu::UVec3 {
+ fn to_gpu(&self) -> gpu::UVec3 {
+ gpu::UVec3::new(self.x, self.y, self.z)
+ }
+}
+
+impl ToGpu for cpu::UVec4 {
+ fn to_gpu(&self) -> gpu::UVec4 {
+ gpu::UVec4::new(self.x, self.y, self.z, self.w)
+ }
+}
\ No newline at end of file
From b37c66a40baa72e4cae23c0c6cde8e17eef6ba6f Mon Sep 17 00:00:00 2001
From: glasspangolin <23103433+glasspangolin@users.noreply.github.com>
Date: Mon, 18 Nov 2024 19:11:52 +1100
Subject: [PATCH 2/2] - Found a nicer workaround to the inline const problem,
although this does involve patching all bevy dependencies to add one line.
This might be palatable because it is a similar style to the removed naga
patch. - Fixed one last example of newer WGPU versions being fussy with u8
cast as u32.
---
.gitignore | 2 ++
Cargo.toml | 34 ++++++++++++++++++++++++++++++
strolle-shaders/src/ref_shading.rs | 2 +-
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index f6433629..3e54d49a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ target
/bevy-strolle/examples/bench-*
/bevy-strolle/examples/scene*
/Cargo.lock
+Cargo.lock
+*.lock
diff --git a/Cargo.toml b/Cargo.toml
index 5943300c..05ac7740 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,37 @@ members = [
"strolle-shaders",
]
+[patch."crates-io"]
+bevy = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_render = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_ptr = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_utils = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_tasks = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_reflect = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_mikktspace = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_ecs = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_math = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_app = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_color = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_core = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_asset = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_a11y = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_time = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_hierarchy = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_window = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_diagnostic = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_gilrs = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_transform = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_state = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_winit = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_audio = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_core_pipeline = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_animation = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_scene = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_sprite = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_pbr = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_gizmos = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_text = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_gltf = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_ui = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
+bevy_internal = { git = "https://github.com/glasspangolin/bevy", branch = "v0.14.2-strolle" }
\ No newline at end of file
diff --git a/strolle-shaders/src/ref_shading.rs b/strolle-shaders/src/ref_shading.rs
index e71214a2..a6c1acaf 100644
--- a/strolle-shaders/src/ref_shading.rs
+++ b/strolle-shaders/src/ref_shading.rs
@@ -50,7 +50,7 @@ pub fn main(
// -------------------------------------------------------------------------
- if params.depth == u8::MAX as u32 {
+ if params.depth == 255u32 {
let prev_color = if camera.is_eq(*prev_camera) {
colors.read(screen_pos)
} else {