diff --git a/assignment-1d/.cargo/config.toml b/assignment-1d/.cargo/config.toml new file mode 100644 index 000000000..70f9eae --- /dev/null +++ b/assignment-1d/.cargo/config.toml @@ -0,0 +1,2 @@ +[registries.crates-io] +protocol = "sparse" diff --git a/assignment-1d/Cargo.lock b/assignment-1d/Cargo.lock index 2122d90..2ce421f 100644 --- a/assignment-1d/Cargo.lock +++ b/assignment-1d/Cargo.lock @@ -42,6 +42,7 @@ dependencies = [ "anyhow", "base64", "clap", + "contracts", "derivative", "generator", "itertools", @@ -142,6 +143,17 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "contracts" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d1429e3bd78171c65aa010eabcdf8f863ba3254728dbfb0ad4b1545beac15c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "crossbeam-channel" version = "0.5.6" diff --git a/assignment-1d/Cargo.toml b/assignment-1d/Cargo.toml index 624576f..a0371dc 100644 --- a/assignment-1d/Cargo.toml +++ b/assignment-1d/Cargo.toml @@ -22,6 +22,7 @@ path = "src/main.rs" anyhow = { version = "1.0.68", features = ["backtrace"] } base64 = "0.21.0" clap = { version = "4.1.4", features = ["cargo", "derive"] } +contracts = "0.6.3" derivative = "2.2.0" generator = "0.7.2" itertools = "0.10.5" diff --git a/assignment-1d/Makefile b/assignment-1d/Makefile index ab3e26a..27163f4 100644 --- a/assignment-1d/Makefile +++ b/assignment-1d/Makefile @@ -2,6 +2,13 @@ .PRECIOUS: $(EXAMPLES_PPM) +DEBUG := +RELEASE_FLAG := --release + +ifeq ($(DEBUG),1) + RELEASE_FLAG := +endif + RAYTRACER_FLAGS := DOCKER := docker ZIP := zip @@ -35,7 +42,7 @@ $(HANDIN): $(BINARY) Makefile Cargo.toml Cargo.lock README.md $(EXAMPLES_PNG) $( $(ZIP) -r $@ src examples $^ examples/%.ppm: examples/%.txt $(SOURCES) - cargo run --release -- -o $@ $(RAYTRACER_FLAGS) $< + cargo run $(RELEASE_FLAG) -- -o $@ $(RAYTRACER_FLAGS) $< examples/%.png: examples/%.ppm convert $< $@ diff --git a/assignment-1d/src/lib.rs b/assignment-1d/src/lib.rs index 597ee48..77efd4e 100644 --- a/assignment-1d/src/lib.rs +++ b/assignment-1d/src/lib.rs @@ -3,6 +3,8 @@ use nalgebra::{Vector2, Vector3}; #[macro_use] extern crate anyhow; #[macro_use] +extern crate contracts; +#[macro_use] extern crate derivative; #[macro_use] extern crate tracing; diff --git a/assignment-1d/src/ray.rs b/assignment-1d/src/ray.rs index 553978a..b5d74dc 100644 --- a/assignment-1d/src/ray.rs +++ b/assignment-1d/src/ray.rs @@ -28,4 +28,14 @@ impl Ray { pub fn eval(&self, time: f64) -> Point { self.origin + self.direction * time } + + /// Check if any of the components is NaN + pub fn has_nan(&self) -> bool { + self.origin.x.is_nan() + || self.origin.y.is_nan() + || self.origin.z.is_nan() + || self.direction.x.is_nan() + || self.direction.y.is_nan() + || self.direction.z.is_nan() + } } diff --git a/assignment-1d/src/scene/illumination.rs b/assignment-1d/src/scene/illumination.rs index 23fe1e0..6944507 100644 --- a/assignment-1d/src/scene/illumination.rs +++ b/assignment-1d/src/scene/illumination.rs @@ -137,24 +137,24 @@ impl Scene { fresnel_coefficient * r_lambda }; - let transparency = { - let n = intersection_context.normal; - let i = incident_ray.direction; + let (eta_i, eta_t) = match intersection_context.exiting { + true => (material.eta, 1.0), + false => (1.0, material.eta), + }; - let (eta_i, eta_t) = match intersection_context.exiting { - true => (material.eta, 1.0), - false => (1.0, material.eta), - }; + let transparency = if eta_t < 1.0 { + Vector::default() + } else { + let n = intersection_context.normal.normalize(); + let i = incident_ray.direction.normalize(); + + assert!(eta_t != 0.0, "wtf eta_t is 0"); // Slide 69 let cos_theta_i = dot(i, n); - assert!(cos_theta_i != std::f64::NAN); let sin_theta_i = (1.0 - cos_theta_i.powi(2)).sqrt(); - assert!(sin_theta_i != std::f64::NAN); let sin_theta_t = (eta_i / eta_t) * sin_theta_i; - assert!(sin_theta_t != std::f64::NAN); let cos_theta_t = (1.0 - sin_theta_t.powi(2)).sqrt(); - assert!(cos_theta_t != std::f64::NAN); let fresnel_coefficient = self.compute_fresnel_coefficient(&material, i, n); @@ -172,6 +172,12 @@ impl Scene { let origin = origin + JITTER_CONST * t; let ray = Ray::new(origin, t); + assert!( + !ray.has_nan(), + "ray is nan WTF {cos_theta_i} {sin_theta_i} ({}) {sin_theta_t} {cos_theta_t} | normal: {:?}", + eta_i / eta_t, + intersection_context.normal, + ); let t_lambda = self.trace_single_ray(ray, depth + 1)?; (1.0 - fresnel_coefficient) * (1.0 - material.alpha) * t_lambda diff --git a/assignment-1d/src/scene/materials.rs b/assignment-1d/src/scene/materials.rs deleted file mode 100644 index c70520c..000000000 --- a/assignment-1d/src/scene/materials.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::data::Material; - -pub struct MaterialStack<'a> { - stack: Vec<&'a f64>, -} - diff --git a/assignment-1d/src/scene/mod.rs b/assignment-1d/src/scene/mod.rs index 6cd69d6..2c31229 100644 --- a/assignment-1d/src/scene/mod.rs +++ b/assignment-1d/src/scene/mod.rs @@ -5,16 +5,15 @@ pub mod input_file; pub mod object; pub mod sphere; pub mod texture; -pub mod triangle; pub mod tracing; -pub mod materials; +pub mod triangle; use crate::image::Color; use crate::{Point, Point2, Vector}; use self::data::{Attenuation, DepthCueing, Light, Material}; use self::object::Object; -use self::texture::{Texture, NormalMap}; +use self::texture::{NormalMap, Texture}; #[derive(Debug, Default)] pub struct Scene { diff --git a/flake.lock b/flake.lock index 2335fbb..35c5944 100644 --- a/flake.lock +++ b/flake.lock @@ -6,11 +6,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1674240251, - "narHash": "sha256-AVMmf/CtcGensTZmMicToDpOwySEGNKYgRPC7lu3m8w=", + "lastModified": 1679638953, + "narHash": "sha256-OFATLLft/9vXHf+zqa6OQGTQ2rrCuD97KRzsrPsJRdY=", "owner": "nix-community", "repo": "fenix", - "rev": "d8067f4d1d3d30732703209bec5ca7d62aaececc", + "rev": "1336152ce31c0f781ae121aa297a5699c642a9fe", "type": "github" }, "original": { @@ -35,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1673796341, - "narHash": "sha256-1kZi9OkukpNmOaPY7S5/+SlCDOuYnP3HkXHvNDyLQcc=", + "lastModified": 1679437018, + "narHash": "sha256-vOuiDPLHSEo/7NkiWtxpHpHgoXoNmrm+wkXZ6a072Fc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6dccdc458512abce8d19f74195bb20fdb067df50", + "rev": "19cf008bb18e47b6e3b4e16e32a9a4bdd4b45f7e", "type": "github" }, "original": { @@ -51,16 +51,17 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1667629849, - "narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=", + "lastModified": 1679721255, + "narHash": "sha256-R199ew5XtM/fXy0P9Ls+sOtYWc9Cubz2c2Ept0csUVg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "3bacde6273b09a21a8ccfba15586fb165078fb62", + "rev": "798e23beab9b5cba4d6f05e8b243e1d4535770f3", "type": "github" }, "original": { - "id": "nixpkgs", - "type": "indirect" + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" } }, "root": { @@ -73,11 +74,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1674162026, - "narHash": "sha256-iY0bxoVE7zAZmp0BB/m5hZW5pWHUfgntDvc1m2zyt/U=", + "lastModified": 1679520343, + "narHash": "sha256-AJGSGWRfoKWD5IVTu1wEsR990wHbX0kIaolPqNMEh0c=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "6e52c64031825920983515b9e975e93232739f7f", + "rev": "eb791f31e688ae00908eb75d4c704ef60c430a92", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index ea8d474..cb83924 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,8 @@ { - inputs = { fenix.url = "github:nix-community/fenix"; }; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs"; + fenix.url = "github:nix-community/fenix"; + }; outputs = { self, nixpkgs, flake-utils, fenix }: flake-utils.lib.eachDefaultSystem (system: