ft: 14: random sphere render
This commit is contained in:
172
src/main.rs
172
src/main.rs
@@ -6,71 +6,18 @@ mod ray;
|
|||||||
mod scenes;
|
mod scenes;
|
||||||
mod vec3;
|
mod vec3;
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::camera::Camera;
|
||||||
use crate::objects::materials::dielectric::Dielectric;
|
use crate::objects::materials::dielectric::Dielectric;
|
||||||
use crate::objects::materials::lambertian::{Lambertian, Metal};
|
use crate::objects::materials::lambertian::{Lambertian, Metal};
|
||||||
use crate::objects::materials::traits::Material;
|
|
||||||
use crate::objects::sphere::Sphere;
|
use crate::objects::sphere::Sphere;
|
||||||
use crate::objects::traits::Hittable;
|
use crate::objects::traits::Hittable;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::scenes::scene::Scene;
|
|
||||||
use crate::vec3::Vec3;
|
use crate::vec3::Vec3;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use log::info;
|
|
||||||
use pretty_env_logger;
|
use pretty_env_logger;
|
||||||
use rand::RngExt;
|
use rand::RngExt;
|
||||||
use rand::seq::IndexedRandom;
|
|
||||||
|
|
||||||
fn random_material() -> Arc<dyn Material> {
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
let col = Vec3::new(rng.random(), rng.random(), rng.random());
|
|
||||||
match rng.random_range(0..3) {
|
|
||||||
0 => Arc::new(Lambertian::new(col, 1.)),
|
|
||||||
1 => Arc::new(Metal::new(col, 1., rng.random())),
|
|
||||||
2 => Arc::new(Dielectric::new(rng.random_range(0.3..1.9))),
|
|
||||||
_ => Arc::new(Metal::new(col, 0., rng.random())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn random_sphere_on_floor<T: Hittable>(
|
|
||||||
materials: &Vec<Arc<dyn Material>>,
|
|
||||||
existing: &Vec<T>,
|
|
||||||
max_size: f32,
|
|
||||||
) -> Sphere {
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
let r = rng.random_range(0.1..max_size);
|
|
||||||
let mut sphere = Sphere::xyz(
|
|
||||||
rng.random_range((-50.)..50.),
|
|
||||||
rng.random_range(0.1..max_size),
|
|
||||||
rng.random_range((-50.)..50.),
|
|
||||||
r,
|
|
||||||
materials.choose(&mut rng).unwrap().clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut isct = true;
|
|
||||||
let mut attempts_left = 49;
|
|
||||||
while isct && attempts_left > 0 {
|
|
||||||
isct = false;
|
|
||||||
for h in existing {
|
|
||||||
if h.inside(&h.closest_on_surface(sphere.center())) {
|
|
||||||
info!("Generating sphere failed, {} attempts left", attempts_left);
|
|
||||||
isct = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isct {
|
|
||||||
sphere.set_center(Vec3::new(
|
|
||||||
rng.random_range(0.5..100.),
|
|
||||||
r,
|
|
||||||
rng.random_range(0.5..100.),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
attempts_left -= 1;
|
|
||||||
}
|
|
||||||
sphere
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement scene serialization
|
// TODO: implement scene serialization
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -78,35 +25,94 @@ fn main() {
|
|||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
|
|
||||||
// TODO: use cli arg for scenefile
|
// TODO: use cli arg for scenefile
|
||||||
let json_file = "./scenes/scene.json";
|
// let json_file = "./scenes/scene.json";
|
||||||
// let json_file = "./scenes/failsMatBounds.json";
|
// let json_str = fs::read_to_string(json_file).expect("Reading specified scene file failed!");
|
||||||
let json_str = fs::read_to_string(json_file).expect("Reading specified scene file failed!");
|
// let mut scene: Scene = serde_json::from_str(&json_str).unwrap();
|
||||||
let mut scene: Scene = serde_json::from_str(&json_str).unwrap();
|
// scene.render();
|
||||||
scene.render();
|
|
||||||
|
|
||||||
// random spheres code; thought: make this available as cli flag?
|
// random spheres code; thought: make this available as cli flag?
|
||||||
// let mut materials: Vec<Arc<dyn Material>> = vec![Arc::new(Lambertian::rgb(0.1, 0.1, 0.2, 0.8))];
|
let ground = Lambertian::rgb(0.5, 0.5, 0.5, 1.);
|
||||||
// for i in 0..15 {
|
let mut world: Vec<Arc<dyn Hittable>> = vec![Arc::new(Sphere::xyz(
|
||||||
// info!("Generating {}th material.", i + 1);
|
0.,
|
||||||
// materials.push(random_material());
|
-1000.,
|
||||||
// }
|
0.,
|
||||||
//
|
1000.,
|
||||||
// let mut world = vec![Sphere::xyz(0., -1000.5, -1., 1000., materials[0].clone())];
|
Arc::new(ground),
|
||||||
// for i in 0..40 {
|
))];
|
||||||
// info!("Generating {}th sphere.", i + 1);
|
|
||||||
// world.push(random_sphere_on_floor(
|
let mut rng = rand::rng();
|
||||||
// &materials,
|
let point = Vec3::new(4., 0.2, 0.);
|
||||||
// &world,
|
for a in -11..11 {
|
||||||
// ((i + 1) as f32).ln() + (15. as f32).log(10.),
|
for b in -11..11 {
|
||||||
// ));
|
let mat = rng.random_range((0.)..1.);
|
||||||
// }
|
let center = Vec3::new(
|
||||||
//
|
a as f32 + 0.9 * rng.random_range((0.)..1.),
|
||||||
// // let mut c = Camera::new(400, 300);
|
0.2,
|
||||||
// let mut c = Camera::new(1920, 1080);
|
b as f32 + 0.9 * rng.random_range((0.)..1.),
|
||||||
// c.set_fov(60.);
|
);
|
||||||
// c.set_anti_alias_rate(1);
|
|
||||||
// c.set_max_depth(10);
|
if (center - point).length() > 0.9 {
|
||||||
// c.set_look_from(Vec3::new(-60., 10., 1.));
|
if mat < 0.8 {
|
||||||
// c.set_look_at(Vec3::new(0., 0., 0.));
|
// diffuse
|
||||||
// c.render(&world);
|
world.push(Arc::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
0.2,
|
||||||
|
Arc::new(Lambertian::new(Vec3::random() * Vec3::random(), 1.)),
|
||||||
|
)));
|
||||||
|
} else if mat < 0.95 {
|
||||||
|
// metal
|
||||||
|
world.push(Arc::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
0.2,
|
||||||
|
Arc::new(Metal::rgb(
|
||||||
|
rng.random_range(0.5..1.),
|
||||||
|
rng.random_range(0.5..1.),
|
||||||
|
rng.random_range(0.5..1.),
|
||||||
|
1.,
|
||||||
|
rng.random_range((0.)..0.5),
|
||||||
|
)),
|
||||||
|
)));
|
||||||
|
} else {
|
||||||
|
// glass
|
||||||
|
world.push(Arc::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
0.2,
|
||||||
|
Arc::new(Dielectric::new(1.5)),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world.push(Arc::new(Sphere::xyz(
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
Arc::new(Dielectric::new(1.5)),
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Sphere::xyz(
|
||||||
|
-4.,
|
||||||
|
1.,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
Arc::new(Lambertian::rgb(0.4, 0.2, 0.1, 1.)),
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Sphere::xyz(
|
||||||
|
4.,
|
||||||
|
1.,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
Arc::new(Metal::rgb(0.7, 0.6, 0.5, 1., 0.)),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let mut c = Camera::new(1920, 1080);
|
||||||
|
c.set_fov(20.);
|
||||||
|
c.set_anti_alias_rate(23);
|
||||||
|
c.set_max_depth(50);
|
||||||
|
c.set_look_from(Vec3::new(13., 2., 3.));
|
||||||
|
c.set_look_at(Vec3::new(0., 0., 0.));
|
||||||
|
c.add_defocus_blur(0.6, 10.);
|
||||||
|
|
||||||
|
c.render(&world);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user