diff --git a/.gitignore b/.gitignore index 5b64043..fba185b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .target +**.exr diff --git a/Cargo.lock b/Cargo.lock index 95b5fda..28fe388 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,1078 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitstream-io" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b81e1519b0d82120d2fd469d5bfb2919a9361c48b02d82d04befc1cdd2002452" + +[[package]] +name = "built" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cc" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide 0.7.4", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fdeflate" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide 0.8.0", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "image" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "png" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f0bfd976333248de2078d350bfdf182ff96e168a24d23d2436cef320dd4bdd" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rgb", +] + [[package]] name = "ray-tracing-core" version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "ray-tracing-image" +version = "0.1.0" +dependencies = [ + "image", + "rand", + "ray-tracing-core", + "ray-tracing-scene", + "rayon", +] + +[[package]] +name = "ray-tracing-scene" +version = "0.1.0" +dependencies = [ + "rand", + "ray-tracing-core", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +dependencies = [ + "zune-core", +] diff --git a/Cargo.toml b/Cargo.toml index bf36457..0c703a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ [workspace] -members = [ "ray-tracing-core"] +members = [ "ray-tracing-core", "ray-tracing-image", "ray-tracing-scene"] resolver = "2" diff --git a/ray-tracing-core/Cargo.toml b/ray-tracing-core/Cargo.toml index f235845..acf38bc 100644 --- a/ray-tracing-core/Cargo.toml +++ b/ray-tracing-core/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] +rand = "0.8.5" diff --git a/ray-tracing-core/src/camera.rs b/ray-tracing-core/src/camera.rs new file mode 100644 index 0000000..affdca4 --- /dev/null +++ b/ray-tracing-core/src/camera.rs @@ -0,0 +1,74 @@ +use crate::prelude::*; +use rand::Rng; + +pub trait Camera { + fn forward(&self, x: u32, y: u32, rng: &mut R) -> Ray; + fn width(&self) -> u32; + fn height(&self) -> u32; +} + +pub struct BasicCamera { + width: u32, + height: u32, + pos: Pos3, + dir: Dir3, + h: Dir3, + v: Dir3, +} + +impl BasicCamera { + pub fn new( + width: u32, + height: u32, + pos: Pos3, + dir: Dir3, + up: Dir3, + horizontal_fov: Float, + ) -> Self { + assert!(horizontal_fov < FloatConsts::PI); + let dir = dir.normalize(); + let up = up.normalize(); + let l = Float::sin(0.5 * horizontal_fov); + let h = l * Dir3::cross(dir, up); + let v = l * ((height as Float) / (width as Float)) * Dir3::cross(dir, h.normalize()); + Self { + width, + height, + pos, + dir, + h, + v, + } + } + + pub fn from_look_at( + width: u32, + height: u32, + pos: Pos3, + look_at: Pos3, + up: Dir3, + horizontal_fov: Float, + ) -> Self { + Self::new(width, height, pos, look_at - pos, up, horizontal_fov) + } +} + +impl Camera for BasicCamera { + fn forward(&self, x: u32, y: u32, rng: &mut R) -> Ray { + // normalize x and y to -0.5 to 0.5 + let x = ((x as Float + rng.gen::()) / (self.width as Float)) - 0.5; + let y = ((y as Float + rng.gen::()) / (self.height as Float)) - 0.5; + + let dir = self.dir + x * self.h + y * self.v; + + Ray::new(self.pos, dir.normalize(), 0.0) + } + + fn width(&self) -> u32 { + self.width + } + + fn height(&self) -> u32 { + self.height + } +} diff --git a/ray-tracing-core/src/color.rs b/ray-tracing-core/src/color.rs new file mode 100644 index 0000000..a0fd1a8 --- /dev/null +++ b/ray-tracing-core/src/color.rs @@ -0,0 +1,67 @@ +use crate::prelude::*; +use std::ops::{Add, AddAssign, Div}; + +#[derive(Debug, Clone, Copy)] +pub struct Color { + r: Float, + g: Float, + b: Float, +} + +impl Color { + pub fn new(r: Float, g: Float, b: Float) -> Self { + Self { r, g, b } + } + + pub fn r(self) -> Float { + self.r + } + + pub fn g(self) -> Float { + self.g + } + + pub fn b(self) -> Float { + self.b + } + + pub fn gray(x: Float) -> Self { + Self::new(x, x, x) + } + + pub fn black() -> Self { + Self::gray(0.0) + } +} + +impl Add for Color { + type Output = Color; + + fn add(self, rhs: Self) -> Self::Output { + Self { + r: self.r + rhs.r, + g: self.g + rhs.g, + b: self.b + rhs.b, + } + } +} + +impl AddAssign for Color { + fn add_assign(&mut self, rhs: Self) { + self.r += rhs.r; + self.g += rhs.g; + self.b += rhs.b; + } +} + +impl Div for Color { + type Output = Color; + + fn div(self, rhs: Float) -> Self::Output { + Self { + r: self.r / rhs, + g: self.g / rhs, + b: self.b / rhs, + } + } +} diff --git a/ray-tracing-core/src/lib.rs b/ray-tracing-core/src/lib.rs index fbf7452..34fc5c5 100644 --- a/ray-tracing-core/src/lib.rs +++ b/ray-tracing-core/src/lib.rs @@ -1,11 +1,16 @@ +pub mod camera; +pub mod color; pub mod material; pub mod math; pub mod ray; +pub mod renderer; pub mod scene; pub mod prelude { - pub type Float = f64; + pub type Float = f32; + pub use crate::color::Color; pub use crate::material::Material; - pub use crate::math::{Dir3, Pos3}; + pub use crate::math::*; pub use crate::ray::Ray; + pub use std::f32::consts as FloatConsts; } diff --git a/ray-tracing-core/src/material.rs b/ray-tracing-core/src/material.rs index a799c9b..f9b81df 100644 --- a/ray-tracing-core/src/material.rs +++ b/ray-tracing-core/src/material.rs @@ -1 +1,15 @@ -pub trait Material {} +use crate::prelude::*; +use rand::Rng; + +/// All calculations for the material are done a tangent space of the intersection. +pub trait Material { + fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Color; +} + +pub struct DefaultMaterial {} + +impl Material for DefaultMaterial { + fn eval(&self, _w_in: Dir3, _w_out: Dir3, rng: &mut R) -> Color { + Color::black() + } +} diff --git a/ray-tracing-core/src/math.rs b/ray-tracing-core/src/math/dir3.rs similarity index 64% rename from ray-tracing-core/src/math.rs rename to ray-tracing-core/src/math/dir3.rs index 281f379..c72cc07 100644 --- a/ray-tracing-core/src/math.rs +++ b/ray-tracing-core/src/math/dir3.rs @@ -1,54 +1,26 @@ use crate::prelude::*; use std::ops::{Add, Div, Mul, Neg, Sub}; -#[derive(Debug, Clone, Copy)] -pub struct Pos3 { - x: Float, - y: Float, - z: Float, -} - #[derive(Debug, Clone, Copy)] pub struct Dir3 { - x: Float, - y: Float, - z: Float, -} - -impl Pos3 { - pub fn new(x: Float, y: Float, z: Float) -> Self { - Self { x, y, z } - } - - pub fn x(self) -> Float { - self.x - } - pub fn y(self) -> Float { - self.y - } - pub fn z(self) -> Float { - self.z - } - - pub fn zero() -> Self { - Self { - x: 0.0, - y: 0.0, - z: 0.0, - } - } + pub(crate) x: Float, + pub(crate) y: Float, + pub(crate) z: Float, } impl Dir3 { pub fn new(x: Float, y: Float, z: Float) -> Self { Self { x, y, z } } + pub fn x(self) -> Float { self.x } + pub fn y(self) -> Float { self.y } + pub fn z(self) -> Float { self.z } @@ -61,23 +33,32 @@ impl Dir3 { } } + pub fn up() -> Self { + Self::new(0.0, 1.0, 0.0) + } + pub fn normalize(self) -> Self { self / self.length() } - pub fn length(self) -> Float { - Float::sqrt(self.x * self.x + self.y * self.y + self.z * self.z) + + pub fn length_squared(self) -> Float { + self.x * self.x + self.y * self.y + self.z * self.z } -} -impl Sub for Pos3 { - type Output = Dir3; + pub fn length(self) -> Float { + Float::sqrt(self.length_squared()) + } - fn sub(self, rhs: Self) -> Self::Output { - Dir3 { - x: self.x - rhs.x, - y: self.y - rhs.y, - z: self.z - rhs.z, - } + pub fn dot(self, rhs: Self) -> Float { + self.x * rhs.x + self.y * rhs.y + self.z * rhs.z + } + + pub fn cross(self, rhs: Self) -> Self { + Self::new( + self.y * rhs.z - self.z * rhs.y, + self.z * rhs.x - self.x * rhs.z, + self.x * rhs.y - self.y * rhs.x, + ) } } @@ -93,23 +74,11 @@ impl Add for Dir3 { } } -impl Add for Dir3 { - type Output = Pos3; +impl Add for Dir3 { + type Output = pos3::Pos3; - fn add(self, rhs: Pos3) -> Self::Output { - Pos3 { - x: self.x + rhs.x, - y: self.y + rhs.y, - z: self.z + rhs.z, - } - } -} - -impl Add for Pos3 { - type Output = Pos3; - - fn add(self, rhs: Dir3) -> Self::Output { - Pos3 { + fn add(self, rhs: pos3::Pos3) -> Self::Output { + pos3::Pos3 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, @@ -141,6 +110,18 @@ impl Mul for Dir3 { } } +impl Mul for Float { + type Output = Dir3; + + fn mul(self, rhs: Dir3) -> Self::Output { + Dir3 { + x: self * rhs.x, + y: self * rhs.y, + z: self * rhs.z, + } + } +} + impl Div for Dir3 { type Output = Dir3; diff --git a/ray-tracing-core/src/math/mod.rs b/ray-tracing-core/src/math/mod.rs new file mode 100644 index 0000000..6a89f06 --- /dev/null +++ b/ray-tracing-core/src/math/mod.rs @@ -0,0 +1,5 @@ +pub mod dir3; +pub mod pos3; + +pub use dir3::Dir3; +pub use pos3::Pos3; diff --git a/ray-tracing-core/src/math/pos3.rs b/ray-tracing-core/src/math/pos3.rs new file mode 100644 index 0000000..2ed49fa --- /dev/null +++ b/ray-tracing-core/src/math/pos3.rs @@ -0,0 +1,57 @@ +use crate::prelude::*; +use std::ops::{Add, Sub}; + +#[derive(Debug, Clone, Copy)] +pub struct Pos3 { + pub(crate) x: Float, + pub(crate) y: Float, + pub(crate) z: Float, +} + +impl Pos3 { + pub fn new(x: Float, y: Float, z: Float) -> Self { + Self { x, y, z } + } + + pub fn x(self) -> Float { + self.x + } + pub fn y(self) -> Float { + self.y + } + pub fn z(self) -> Float { + self.z + } + + pub fn zero() -> Self { + Self { + x: 0.0, + y: 0.0, + z: 0.0, + } + } +} + +impl Sub for pos3::Pos3 { + type Output = Dir3; + + fn sub(self, rhs: Self) -> Self::Output { + Dir3 { + x: self.x - rhs.x, + y: self.y - rhs.y, + z: self.z - rhs.z, + } + } +} + +impl Add for pos3::Pos3 { + type Output = pos3::Pos3; + + fn add(self, rhs: Dir3) -> Self::Output { + pos3::Pos3 { + x: self.x + rhs.x, + y: self.y + rhs.y, + z: self.z + rhs.z, + } + } +} diff --git a/ray-tracing-core/src/ray.rs b/ray-tracing-core/src/ray.rs index ac3a573..2af8d5e 100644 --- a/ray-tracing-core/src/ray.rs +++ b/ray-tracing-core/src/ray.rs @@ -2,7 +2,25 @@ use crate::prelude::*; #[derive(Debug, Clone, Copy)] pub struct Ray { - pub start: Pos3, - pub dir: Dir3, - pub time: Float, + start: Pos3, + dir: Dir3, + time: Float, +} + +impl Ray { + pub fn new(start: Pos3, dir: Dir3, time: Float) -> Self { + Self { start, dir, time } + } + + pub fn start(self) -> Pos3 { + self.start + } + + pub fn dir(self) -> Dir3 { + self.dir + } + + pub fn time(self) -> Float { + self.time + } } diff --git a/ray-tracing-core/src/renderer.rs b/ray-tracing-core/src/renderer.rs new file mode 100644 index 0000000..c34156d --- /dev/null +++ b/ray-tracing-core/src/renderer.rs @@ -0,0 +1,63 @@ +use std::marker::PhantomData; + +use crate::{camera::Camera, prelude::*, scene::Scene}; +use rand::Rng; + +pub trait ClassicalRenderer { + fn render_pixel(&self, x: u32, y: u32, rng: &mut R) -> Color; + fn width(&self) -> u32; + fn height(&self) -> u32; +} + +pub struct DepthRenderer +where + S: Scene, + C: Camera, + R: Rng, +{ + scene: S, + camera: C, + rng: PhantomData, +} + +impl DepthRenderer +where + S: Scene, + C: Camera, + R: Rng, +{ + pub fn new(scene: S, camera: C) -> Self { + Self { + scene, + camera, + rng: PhantomData {}, + } + } +} + +impl ClassicalRenderer for DepthRenderer +where + S: Scene, + C: Camera, + R: Rng, +{ + fn render_pixel(&self, x: u32, y: u32, rng: &mut R) -> Color { + let r = self.camera.forward(x, y, rng); + + if let Some(i) = self.scene.intersect(r, 0.0, Float::INFINITY) { + // Color::gray(1.0 / i.t()) + let c = 0.5 * (i.normal() + Dir3::new(1.0, 1.0, 1.0)); + Color::new(c.x, c.y, c.z) + } else { + Color::black() + } + } + + fn width(&self) -> u32 { + self.camera.width() + } + + fn height(&self) -> u32 { + self.camera.height() + } +} diff --git a/ray-tracing-core/src/scene.rs b/ray-tracing-core/src/scene.rs index 8c28af3..66e05d9 100644 --- a/ray-tracing-core/src/scene.rs +++ b/ray-tracing-core/src/scene.rs @@ -1,24 +1,34 @@ use crate::prelude::*; +use rand::Rng; -pub trait Scene { - fn intersect(&self, ray: Ray, min: Float, max: Float) -> Option>; +pub trait Scene { + fn intersect(&self, ray: Ray, min: Float, max: Float) -> Option>; } -pub struct Intersection<'sc> { +pub struct Intersection<'sc, R: Rng> { t: Float, - material: &'sc dyn Material, + normal: Dir3, + material: &'sc dyn Material, } -impl<'sc> Intersection<'sc> { - pub fn new(t: Float, material: &'sc dyn Material) -> Self { - Self { t, material } +impl<'sc, R: Rng> Intersection<'sc, R> { + pub fn new(t: Float, normal: Dir3, material: &'sc dyn Material) -> Self { + Self { + t, + normal, + material, + } } pub fn t(&self) -> Float { self.t } - pub fn material(&self) -> &'sc dyn Material { + pub fn normal(&self) -> Dir3 { + self.normal + } + + pub fn material(&self) -> &'sc dyn Material { self.material } } diff --git a/ray-tracing-image/Cargo.toml b/ray-tracing-image/Cargo.toml new file mode 100644 index 0000000..2c289fd --- /dev/null +++ b/ray-tracing-image/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ray-tracing-image" +version = "0.1.0" +edition = "2021" + +[dependencies] +image = "0.25.2" +rand = { version = "0.8.5", features = ["small_rng"] } +ray-tracing-core = { path = "../ray-tracing-core" } +ray-tracing-scene = { path = "../ray-tracing-scene" } +rayon = "1.10.0" diff --git a/ray-tracing-image/src/main.rs b/ray-tracing-image/src/main.rs new file mode 100644 index 0000000..6b5abb6 --- /dev/null +++ b/ray-tracing-image/src/main.rs @@ -0,0 +1,52 @@ +use image::{ImageBuffer, ImageResult, Rgb}; +use rand::{rngs::SmallRng, SeedableRng}; +use ray_tracing_core::{ + camera::BasicCamera, + prelude::*, + renderer::{ClassicalRenderer, DepthRenderer}, +}; +use ray_tracing_scene::BasicScene; +use rayon::prelude::*; +use std::path::Path; + +fn render_image + Sync>( + renderer: C, + outputfilename: impl AsRef, + samples_per_pixel: usize, +) -> ImageResult<()> { + let mut data = vec![Color::black(); (renderer.width() * renderer.height()) as usize]; + + data.par_iter_mut().enumerate().for_each(|(i, c)| { + let x = (i % renderer.width() as usize) as u32; + let y = (i / renderer.width() as usize) as u32; + + let mut rng = SmallRng::seed_from_u64((x + y * renderer.width()) as u64); + for _ in 0..samples_per_pixel { + *c += renderer.render_pixel(x, y, &mut rng) / (samples_per_pixel as Float); + } + }); + + let img = ImageBuffer::from_fn(renderer.width(), renderer.height(), |x, y| { + let c = data[(x + y * renderer.width()) as usize]; + Rgb::([c.r(), c.g(), c.b()]) + }); + + img.save(outputfilename) +} + +fn main() -> ImageResult<()> { + let s = BasicScene::new(); + + let c = BasicCamera::new( + 640, + 400, + Pos3::new(-10.0, 0.0, 0.0), + Dir3::new(1.0, 0.0, 0.0), + Dir3::up(), + Float::to_radians(90.0), + ); + + let r = DepthRenderer::new(s, c); + + render_image(r, "test.exr", 16) +} diff --git a/ray-tracing-scene/Cargo.toml b/ray-tracing-scene/Cargo.toml new file mode 100644 index 0000000..09f2662 --- /dev/null +++ b/ray-tracing-scene/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ray-tracing-scene" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.5" +ray-tracing-core = { path = "../ray-tracing-core" } diff --git a/ray-tracing-scene/src/lib.rs b/ray-tracing-scene/src/lib.rs new file mode 100644 index 0000000..8db47da --- /dev/null +++ b/ray-tracing-scene/src/lib.rs @@ -0,0 +1,51 @@ +use rand::Rng; +use ray_tracing_core::material::DefaultMaterial; +use ray_tracing_core::prelude::*; +use ray_tracing_core::scene::{Intersection, Scene}; + +pub mod sphere; + +pub struct BasicScene { + spheres: Vec<(Pos3, Float)>, +} + +impl BasicScene { + pub fn new() -> Self { + Self { + spheres: vec![(Pos3::zero(), 1.0), (Pos3::new(0.0, 0.0, 2.5), 2.0)], + } + } +} + +impl Scene for BasicScene { + fn intersect(&self, ray: Ray, min: Float, max: Float) -> Option> { + let mut intersection: Option> = None; + + for &(c, r) in &self.spheres { + let offset = ray.start() - c; + let p = Dir3::dot(ray.dir(), offset); + let delta = p * p - (offset.length_squared() - r * r); + + if delta >= 0.0 { + let d = -p - Float::sqrt(delta); + + let int = Intersection::new( + d, + ((ray.start() + d * ray.dir()) - c).normalize(), + &DefaultMaterial {}, + ); + if d >= min && d <= max { + if let Some(i) = intersection.as_ref() { + if i.t() > d { + intersection.replace(int); + } + } else { + intersection = Some(int) + } + } + } + } + + intersection + } +} diff --git a/ray-tracing-scene/src/sphere.rs b/ray-tracing-scene/src/sphere.rs new file mode 100644 index 0000000..e69de29