diff --git a/rend3-test/src/helpers.rs b/rend3-test/src/helpers.rs index c9271366..59dad809 100644 --- a/rend3-test/src/helpers.rs +++ b/rend3-test/src/helpers.rs @@ -62,7 +62,7 @@ impl TestRunner { ], rend3::types::Handedness::Left, ) - .with_indices(vec![0, 1, 2, 0, 2, 3]) + .with_indices(vec![0, 2, 1, 0, 3, 2]) .build() .unwrap(); diff --git a/rend3-test/src/runner.rs b/rend3-test/src/runner.rs index 7b0344e6..e25a4eff 100644 --- a/rend3-test/src/runner.rs +++ b/rend3-test/src/runner.rs @@ -16,6 +16,7 @@ use wgpu::{ use crate::{helpers::CaptureDropGuard, ThresholdSet}; +#[derive(Clone)] pub struct FrameRenderSettings { size: u32, samples: SampleCount, @@ -129,14 +130,7 @@ impl TestRunner { TestRunnerBuilder::new() } - pub async fn render_frame(&self, settings: FrameRenderSettings) -> Result { - let buffer = self.renderer.device.create_buffer(&wgpu::BufferDescriptor { - label: Some("Test output buffer"), - size: (settings.size * settings.size * 4) as u64, - usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, - mapped_at_creation: false, - }); - + pub fn process_events(&self, settings: FrameRenderSettings) -> wgpu::Texture { let texture = self.renderer.device.create_texture(&TextureDescriptor { label: Some("Test output image"), size: Extent3d { @@ -179,6 +173,19 @@ impl TestRunner { graph.execute(&self.renderer, &mut eval_output); + texture + } + + pub async fn render_frame(&self, settings: FrameRenderSettings) -> Result { + let buffer = self.renderer.device.create_buffer(&wgpu::BufferDescriptor { + label: Some("Test output buffer"), + size: (settings.size * settings.size * 4) as u64, + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + let texture = self.process_events(settings.clone()); + let mut encoder = self .renderer .device diff --git a/rend3-test/tests/msaa.rs b/rend3-test/tests/msaa.rs index 6ccc550d..f92c7241 100644 --- a/rend3-test/tests/msaa.rs +++ b/rend3-test/tests/msaa.rs @@ -48,3 +48,48 @@ pub async fn triangle() -> anyhow::Result<()> { Ok(()) } + +#[test_attr] +pub async fn sample_coverage() -> anyhow::Result<()> { + let iad = no_gpu_return!(rend3::create_iad(None, None, None, None).await) + .context("InstanceAdapterDevice creation failed")?; + + let Ok(runner) = TestRunner::builder().iad(iad.clone()).handedness(Handedness::Left).build().await else { + return Ok(()); + }; + + let material = runner.add_unlit_material(Vec4::ONE); + + // Make a plane whose (0, 0) is at the top left, and is 1 unit large. + let base_matrix = Mat4::from_translation(Vec3::new(0.5, 0.5, 0.0)) * Mat4::from_scale(Vec3::new(0.5, 0.5, 1.0)); + // 64 x 64 grid of planes + let mut planes = Vec::with_capacity(64 * 64); + for x in 0..64 { + for y in 0..64 { + planes.push(runner.plane( + material.clone(), + Mat4::from_translation(Vec3::new(x as f32, y as f32, 0.0)) + * Mat4::from_scale(Vec3::new(1.0 - (x as f32 / 63.0), 1.0 - (y as f32 / 63.0), 1.0)) + * base_matrix, + )); + } + runner.process_events(FrameRenderSettings::new()); + } + + runner.set_camera_data(Camera { + projection: rend3::types::CameraProjection::Raw(Mat4::orthographic_lh(0.0, 64.0, 64.0, 0.0, 0.0, 1.0)), + view: Mat4::IDENTITY, + }); + + for samples in SampleCount::ARRAY { + runner + .render_and_compare( + FrameRenderSettings::new().samples(samples), + &format!("tests/results/msaa/sample-coverage-{}.png", samples as u8), + 0.0, + ) + .await?; + } + + Ok(()) +} diff --git a/rend3-test/tests/results/msaa/sample-coverage-1.png b/rend3-test/tests/results/msaa/sample-coverage-1.png new file mode 100644 index 00000000..6fd080b0 Binary files /dev/null and b/rend3-test/tests/results/msaa/sample-coverage-1.png differ diff --git a/rend3-test/tests/results/msaa/sample-coverage-4.png b/rend3-test/tests/results/msaa/sample-coverage-4.png new file mode 100644 index 00000000..4db6a56d Binary files /dev/null and b/rend3-test/tests/results/msaa/sample-coverage-4.png differ diff --git a/rend3-test/tests/shadow.rs b/rend3-test/tests/shadow.rs index 88d1b478..b12f93c7 100644 --- a/rend3-test/tests/shadow.rs +++ b/rend3-test/tests/shadow.rs @@ -18,7 +18,7 @@ pub async fn shadows() -> anyhow::Result<()> { let material1 = runner.add_lit_material(Vec4::new(0.25, 0.5, 0.75, 1.0)); - let _plane = runner.plane(material1, Mat4::from_rotation_x(FRAC_PI_2)); + let _plane = runner.plane(material1, Mat4::from_rotation_x(-FRAC_PI_2)); runner.set_camera_data(Camera { projection: rend3::types::CameraProjection::Orthographic { diff --git a/rend3-types/src/lib.rs b/rend3-types/src/lib.rs index b47f3b60..abce0ed3 100644 --- a/rend3-types/src/lib.rs +++ b/rend3-types/src/lib.rs @@ -1167,6 +1167,8 @@ impl TryFrom for SampleCount { } impl SampleCount { + pub const ARRAY: [Self; 2] = [Self::One, Self::Four]; + /// Determines if a resolve texture is needed for this texture. pub fn needs_resolve(self) -> bool { self != Self::One