Skip to content

Commit

Permalink
add proptest usage within ggx tests, along with some fixtures/prop_co…
Browse files Browse the repository at this point in the history
…mpose invocations
  • Loading branch information
gillett-hernandez committed Jul 8, 2024
1 parent 7025efc commit e70b479
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ tobj = "~4.0"
toml = "~0.8"
tracing = "~0.1"
tracing-subscriber = "~0.3"
# pinning to 0.8 because of crate version reasons
ultraviolet = { version = "~0.8", optional = true }

[dev-dependencies]
proptest = "1.5.0"

[target.'cfg(windows)'.dependencies]
win32_notification = "~0.1"

Expand Down
7 changes: 7 additions & 0 deletions proptest-regressions/materials/ggx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 9c0ae291d4fb1b0b7461c99518df9126afd836caa7b93dadd6772b8c1f81fb26 # shrinks to roughness = 8.736748, wi = Vec3(0.54826164, 0.0, -0.83630687), lambda = 400.0, s = Sample2D { x: 0.0, y: 0.0 }
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pub mod tonemap;
pub mod vec2d;
pub mod world;

#[cfg(test)]
pub mod props;

// mauve. universal sign of danger
pub const MAUVE: XYZColor = XYZColor::new(0.5199467, 51.48687, 1.0180528);

Expand Down
123 changes: 123 additions & 0 deletions src/materials/ggx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ impl Material<f32, f32> for GGX {

#[cfg(test)]
mod test {
use proptest::prelude::*;
use crate::props::*;

use math::spectral::BOUNDED_VISIBLE_RANGE;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
Expand Down Expand Up @@ -632,6 +634,127 @@ mod test {
GGX::new(roughness, glass, flat_one, flat_zero, 0, 0)
}

proptest! {
#![proptest_config(ProptestConfig::with_cases(1000))]
#[test]
fn test_ggx(roughness in valid_ggx_roughness(), wi in unit_vector(), lambda in 400.0..800.0f32, s in uniform_sample()) {
let ggx_glass = ggx_glass(roughness);
let fake_hit_record: HitRecord = HitRecord::new(
0.0,
Point3::ZERO,
UV(0.0f32, 0.0f32),
lambda,
Vec3::Z,
MaterialId::Material(0),
0,
None,
);

let maybe_wo = ggx_glass.generate(
fake_hit_record.lambda,
fake_hit_record.uv,
fake_hit_record.transport_mode,
s,
wi,
);
assert!(maybe_wo.is_some());

let wo = maybe_wo.unwrap();
let (orig_f, orig_pdf) = ggx_glass.bsdf(
fake_hit_record.lambda,
fake_hit_record.uv,
fake_hit_record.transport_mode,
wi,
wo,
);

// check swapping wi and wo
let (wi, wo) = (wo, wi);
let (sampled_f, sampled_pdf) = ggx_glass.bsdf(
fake_hit_record.lambda,
fake_hit_record.uv,
fake_hit_record.transport_mode,
wi,
wo,
);
assert!(sampled_f > 0.0, "original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}", orig_f, orig_pdf, sampled_f, sampled_pdf, wi, wo);
assert!(*sampled_pdf >= 0.0, "original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}", orig_f, orig_pdf, sampled_f, sampled_pdf, wi, wo);
assert!(orig_f > 0.0, "original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}", orig_f, orig_pdf, sampled_f, sampled_pdf, wi, wo);
assert!(*orig_pdf >= 0.0, "original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}", orig_f, orig_pdf, sampled_f, sampled_pdf, wi, wo);

}

#[test]
fn test_ggx2(roughness in valid_ggx_roughness(), wi in unit_vector(), wo in unit_vector(), lambda in 400.0..800.0f32) {
let ggx_glass = ggx_glass(roughness);
let fake_hit_record: HitRecord = HitRecord::new(
0.0,
Point3::ZERO,
UV(0.0f32, 0.0f32),
lambda,
Vec3::Z,
MaterialId::Material(0),
0,
None,
);
let (orig_f, orig_pdf) = ggx_glass.bsdf(
fake_hit_record.lambda,
fake_hit_record.uv,
fake_hit_record.transport_mode,
wi,
wo,
);
let (wi, wo) = (wo, wi);
let (sampled_f, sampled_pdf) = ggx_glass.bsdf(
fake_hit_record.lambda,
fake_hit_record.uv,
fake_hit_record.transport_mode,
wi,
wo,
);
assert!(
sampled_f >= 0.0,
"original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}",
orig_f,
orig_pdf,
sampled_f,
sampled_pdf,
wi,
wo
);
assert!(
*sampled_pdf >= 0.0,
"original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}",
orig_f,
orig_pdf,
sampled_f,
sampled_pdf,
wi,
wo
);
assert!(
orig_f >= 0.0,
"original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}",
orig_f,
orig_pdf,
sampled_f,
sampled_pdf,
wi,
wo
);
assert!(
*orig_pdf >= 0.0,
"original f: {:?}, pdf: {:?}, swapped f: {:?}, pdf: {:?}, swapped wi: {:?}, wo: {:?}",
orig_f,
orig_pdf,
sampled_f,
sampled_pdf,
wi,
wo
);
}
}

#[test]
fn test_ggx_functions() {
let mut sampler: Box<dyn Sampler> = Box::new(StratifiedSampler::new(20, 20, 10));
Expand Down
20 changes: 20 additions & 0 deletions src/props.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use math::{random::random_on_unit_sphere, sample::Sample2D, vec::Vec3};
use proptest::prelude::*;

prop_compose! {
pub fn uniform_sample()(u in 0.0..1.0f32, v in 0.0..1.0f32) -> Sample2D {
Sample2D::new(u, v)
}
}

prop_compose! {
pub fn valid_ggx_roughness()(x in 0.0..1.0f32) -> f32 {
(-(x+f32::EPSILON).ln()).recip()
}
}

prop_compose! {
pub fn unit_vector()(s in uniform_sample()) -> Vec3 {
random_on_unit_sphere(s)
}
}

0 comments on commit e70b479

Please sign in to comment.