Change testscene interface
This commit is contained in:
parent
829476c602
commit
0b3daf9441
12 changed files with 313 additions and 223 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait Light<R: Rng>: Sync + Debug {
|
pub trait Light<R: Rng>: Send + Sync + Debug {
|
||||||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color;
|
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// All calculations for the material are done a tangent space of the intersection.
|
/// All calculations for the material are done a tangent space of the intersection.
|
||||||
pub trait Material<R: Rng>: Sync + Debug {
|
pub trait Material<R: Rng>: Send + Sync + Debug {
|
||||||
fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Color;
|
fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Color;
|
||||||
|
|
||||||
fn sample(&self, w_in: Dir3, rng: &mut R) -> SampleResult {
|
fn sample(&self, w_in: Dir3, rng: &mut R) -> SampleResult {
|
||||||
|
|
|
||||||
|
|
@ -91,16 +91,16 @@ fn main() {
|
||||||
let scenes = example_scenes::<rand::rngs::SmallRng>();
|
let scenes = example_scenes::<rand::rngs::SmallRng>();
|
||||||
let mut settings = {
|
let mut settings = {
|
||||||
let scene = scenes.iter().next().unwrap();
|
let scene = scenes.iter().next().unwrap();
|
||||||
let e = (scene.1)();
|
let e = scene.1;
|
||||||
render::RenderSettings {
|
render::RenderSettings {
|
||||||
width: window.inner_size().width,
|
width: window.inner_size().width,
|
||||||
height: window.inner_size().height,
|
height: window.inner_size().height,
|
||||||
scene: scene.0,
|
scene: scene.0,
|
||||||
renderer_id: 0,
|
renderer_id: 0,
|
||||||
camera_pos: e.camera_pos,
|
camera_pos: e.get_camera_pos(),
|
||||||
camera_look_at: e.camera_look_at,
|
camera_look_at: e.get_camera_look_at(),
|
||||||
camera_up: e.camera_up,
|
camera_up: e.get_camera_up(),
|
||||||
camera_horizontal_fov: e.horizontal_fov,
|
camera_horizontal_fov: e.get_horizontal_fov(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -225,11 +225,12 @@ fn main() {
|
||||||
}
|
}
|
||||||
if scene_changed {
|
if scene_changed {
|
||||||
settings_changed = true;
|
settings_changed = true;
|
||||||
let e = scenes[settings.scene]();
|
settings.camera_pos = scenes[settings.scene].get_camera_pos();
|
||||||
settings.camera_pos = e.camera_pos;
|
settings.camera_look_at =
|
||||||
settings.camera_look_at = e.camera_look_at;
|
scenes[settings.scene].get_camera_look_at();
|
||||||
settings.camera_up = e.camera_up;
|
settings.camera_up = scenes[settings.scene].get_camera_up();
|
||||||
settings.camera_horizontal_fov = e.horizontal_fov;
|
settings.camera_horizontal_fov =
|
||||||
|
scenes[settings.scene].get_horizontal_fov();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,7 @@ pub fn render_thread(
|
||||||
|
|
||||||
let example_scenes = examples::example_scenes::<SmallRng>();
|
let example_scenes = examples::example_scenes::<SmallRng>();
|
||||||
|
|
||||||
let e = example_scenes[settings.scene]();
|
let mut scene = example_scenes[settings.scene].get_scene();
|
||||||
let mut scene = (e.scene)();
|
|
||||||
|
|
||||||
let mut camera = BasicCamera::from_look_at(
|
let mut camera = BasicCamera::from_look_at(
|
||||||
settings.width,
|
settings.width,
|
||||||
|
|
@ -88,8 +87,7 @@ pub fn render_thread(
|
||||||
while let Ok(s) = rx.try_recv() {
|
while let Ok(s) = rx.try_recv() {
|
||||||
println!("Settings changed.");
|
println!("Settings changed.");
|
||||||
settings = s;
|
settings = s;
|
||||||
let e = example_scenes[settings.scene]();
|
scene = example_scenes[settings.scene].get_scene();
|
||||||
scene = (e.scene)();
|
|
||||||
camera = BasicCamera::from_look_at(
|
camera = BasicCamera::from_look_at(
|
||||||
settings.width,
|
settings.width,
|
||||||
settings.height,
|
settings.height,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use ray_tracing_core::{
|
||||||
scene::Scene,
|
scene::Scene,
|
||||||
};
|
};
|
||||||
use ray_tracing_renderer::path_tracer_importance::PathTracerImportance;
|
use ray_tracing_renderer::path_tracer_importance::PathTracerImportance;
|
||||||
use ray_tracing_scene::examples::basic_cornell;
|
use ray_tracing_scene::examples::{basic_cornell, ExampleScene};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
@ -45,18 +45,18 @@ fn render_image<
|
||||||
|
|
||||||
fn main() -> ImageResult<()> {
|
fn main() -> ImageResult<()> {
|
||||||
// let s = BasicScene::new();
|
// let s = BasicScene::new();
|
||||||
let s = basic_cornell::scene();
|
let s = basic_cornell::BasicCornell::new();
|
||||||
|
|
||||||
let c = BasicCamera::from_look_at(
|
let c = BasicCamera::from_look_at(
|
||||||
400,
|
400,
|
||||||
400,
|
400,
|
||||||
s.camera_pos,
|
s.get_camera_pos(),
|
||||||
s.camera_look_at,
|
s.get_camera_look_at(),
|
||||||
s.camera_up,
|
s.get_camera_up(),
|
||||||
s.horizontal_fov,
|
s.get_horizontal_fov(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let r = PathTracerImportance::new(400, 400);
|
let r = PathTracerImportance::new(400, 400);
|
||||||
|
|
||||||
render_image(&r, &(s.scene)(), &c, "test.exr", 1048)
|
render_image(&r, &s.get_scene(), &c, "test.exr", 1048)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ pub fn fresnel_real(cos_theta_in: Float, nu1: Float, nu2: Float) -> Float {
|
||||||
0.5 * (rs + rp)
|
0.5 * (rs + rp)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Rng, D: MicrofacetDistribution + Debug + Sync> Material<R> for Microfacet<D> {
|
impl<R: Rng, D: MicrofacetDistribution + Debug + Sync + Send> Material<R> for Microfacet<D> {
|
||||||
fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color {
|
fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color {
|
||||||
if w_out.y() > 0.0 && w_in.y() > 0.0 {
|
if w_out.y() > 0.0 && w_in.y() > 0.0 {
|
||||||
let w_h = (w_in + w_out).normalize();
|
let w_h = (w_in + w_out).normalize();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::cell::OnceCell;
|
||||||
|
|
||||||
use crate::triangle_bvh::{BVHMaterial, Triangle, TriangleBVH};
|
use crate::triangle_bvh::{BVHMaterial, Triangle, TriangleBVH};
|
||||||
|
|
||||||
use super::ExampleScene;
|
use super::ExampleScene;
|
||||||
|
|
@ -5,82 +7,104 @@ use super::ExampleScene;
|
||||||
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
||||||
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
||||||
|
|
||||||
pub fn scene<R: Rng + 'static>() -> ExampleScene<R> {
|
pub struct BasicCornell<R: Rng> {
|
||||||
let f = || {
|
scene: OnceCell<TriangleBVH<R>>,
|
||||||
let side_length = 1.5;
|
}
|
||||||
let light_size = 0.5;
|
|
||||||
let light_offset = 0.01;
|
|
||||||
let box_size = 0.3;
|
|
||||||
let scene = TriangleBVH::new(
|
|
||||||
vec![
|
|
||||||
Pos3::new(side_length, side_length, side_length),
|
|
||||||
Pos3::new(side_length, side_length, -side_length),
|
|
||||||
Pos3::new(side_length, -side_length, side_length),
|
|
||||||
Pos3::new(side_length, -side_length, -side_length),
|
|
||||||
Pos3::new(-side_length, side_length, side_length),
|
|
||||||
Pos3::new(-side_length, side_length, -side_length),
|
|
||||||
Pos3::new(-side_length, -side_length, side_length),
|
|
||||||
Pos3::new(-side_length, -side_length, -side_length),
|
|
||||||
Pos3::new(light_size, side_length - light_offset, light_size),
|
|
||||||
Pos3::new(light_size, side_length - light_offset, -light_size),
|
|
||||||
Pos3::new(-light_size, side_length - light_offset, light_size),
|
|
||||||
Pos3::new(-light_size, side_length - light_offset, -light_size),
|
|
||||||
Pos3::new(box_size, -side_length, 0.0),
|
|
||||||
Pos3::new(0.0, -side_length, -box_size),
|
|
||||||
Pos3::new(-box_size, -side_length, 0.0),
|
|
||||||
Pos3::new(0.0, -side_length, box_size),
|
|
||||||
Pos3::new(0.0, box_size - side_length, 0.0),
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
Triangle::new([0, 1, 2], 0),
|
|
||||||
Triangle::new([1, 3, 2], 0),
|
|
||||||
Triangle::new([0, 4, 1], 0),
|
|
||||||
Triangle::new([1, 4, 5], 0),
|
|
||||||
Triangle::new([2, 3, 6], 0),
|
|
||||||
Triangle::new([3, 7, 6], 0),
|
|
||||||
Triangle::new([0, 2, 4], 1),
|
|
||||||
Triangle::new([6, 4, 2], 1),
|
|
||||||
Triangle::new([1, 5, 3], 2),
|
|
||||||
Triangle::new([7, 3, 5], 2),
|
|
||||||
Triangle::new([8, 10, 9], 3),
|
|
||||||
Triangle::new([11, 9, 10], 3),
|
|
||||||
Triangle::new([12, 13, 16], 4),
|
|
||||||
Triangle::new([13, 14, 16], 4),
|
|
||||||
Triangle::new([14, 15, 16], 4),
|
|
||||||
Triangle::new([15, 12, 16], 4),
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
BVHMaterial {
|
|
||||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))),
|
|
||||||
light: None,
|
|
||||||
},
|
|
||||||
BVHMaterial {
|
|
||||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))),
|
|
||||||
light: None,
|
|
||||||
},
|
|
||||||
BVHMaterial {
|
|
||||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))),
|
|
||||||
light: None,
|
|
||||||
},
|
|
||||||
BVHMaterial {
|
|
||||||
material: None,
|
|
||||||
light: Some(Box::new(AreaLight::new(Color::white() * 18.0))),
|
|
||||||
},
|
|
||||||
BVHMaterial {
|
|
||||||
material: Some(Box::new(Mirror::new(Color::new(1.0, 1.0, 1.0)))),
|
|
||||||
light: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
Box::new(scene) as Box<dyn Scene<R> + Sync>
|
impl<R: Rng> BasicCornell<R> {
|
||||||
};
|
pub fn new() -> Self {
|
||||||
|
BasicCornell {
|
||||||
ExampleScene {
|
scene: OnceCell::new(),
|
||||||
scene: f,
|
}
|
||||||
camera_pos: Pos3::new(-6.0, 0.0, 0.0),
|
}
|
||||||
camera_look_at: Pos3::new(0.0, 0.0, 0.0),
|
}
|
||||||
camera_up: Dir3::up(),
|
|
||||||
horizontal_fov: Float::to_radians(90.0),
|
impl<R: Rng + 'static> ExampleScene<R> for BasicCornell<R> {
|
||||||
|
fn get_scene(&self) -> Box<dyn Scene<R> + Sync> {
|
||||||
|
let s = self.scene.get_or_init(|| {
|
||||||
|
let side_length = 1.5;
|
||||||
|
let light_size = 0.5;
|
||||||
|
let light_offset = 0.01;
|
||||||
|
let box_size = 0.3;
|
||||||
|
TriangleBVH::new(
|
||||||
|
vec![
|
||||||
|
Pos3::new(side_length, side_length, side_length),
|
||||||
|
Pos3::new(side_length, side_length, -side_length),
|
||||||
|
Pos3::new(side_length, -side_length, side_length),
|
||||||
|
Pos3::new(side_length, -side_length, -side_length),
|
||||||
|
Pos3::new(-side_length, side_length, side_length),
|
||||||
|
Pos3::new(-side_length, side_length, -side_length),
|
||||||
|
Pos3::new(-side_length, -side_length, side_length),
|
||||||
|
Pos3::new(-side_length, -side_length, -side_length),
|
||||||
|
Pos3::new(light_size, side_length - light_offset, light_size),
|
||||||
|
Pos3::new(light_size, side_length - light_offset, -light_size),
|
||||||
|
Pos3::new(-light_size, side_length - light_offset, light_size),
|
||||||
|
Pos3::new(-light_size, side_length - light_offset, -light_size),
|
||||||
|
Pos3::new(box_size, -side_length, 0.0),
|
||||||
|
Pos3::new(0.0, -side_length, -box_size),
|
||||||
|
Pos3::new(-box_size, -side_length, 0.0),
|
||||||
|
Pos3::new(0.0, -side_length, box_size),
|
||||||
|
Pos3::new(0.0, box_size - side_length, 0.0),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Triangle::new([0, 1, 2], 0),
|
||||||
|
Triangle::new([1, 3, 2], 0),
|
||||||
|
Triangle::new([0, 4, 1], 0),
|
||||||
|
Triangle::new([1, 4, 5], 0),
|
||||||
|
Triangle::new([2, 3, 6], 0),
|
||||||
|
Triangle::new([3, 7, 6], 0),
|
||||||
|
Triangle::new([0, 2, 4], 1),
|
||||||
|
Triangle::new([6, 4, 2], 1),
|
||||||
|
Triangle::new([1, 5, 3], 2),
|
||||||
|
Triangle::new([7, 3, 5], 2),
|
||||||
|
Triangle::new([8, 10, 9], 3),
|
||||||
|
Triangle::new([11, 9, 10], 3),
|
||||||
|
Triangle::new([12, 13, 16], 4),
|
||||||
|
Triangle::new([13, 14, 16], 4),
|
||||||
|
Triangle::new([14, 15, 16], 4),
|
||||||
|
Triangle::new([15, 12, 16], 4),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
BVHMaterial {
|
||||||
|
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))),
|
||||||
|
light: None,
|
||||||
|
},
|
||||||
|
BVHMaterial {
|
||||||
|
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))),
|
||||||
|
light: None,
|
||||||
|
},
|
||||||
|
BVHMaterial {
|
||||||
|
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))),
|
||||||
|
light: None,
|
||||||
|
},
|
||||||
|
BVHMaterial {
|
||||||
|
material: None,
|
||||||
|
light: Some(Box::new(AreaLight::new(Color::white() * 18.0))),
|
||||||
|
},
|
||||||
|
BVHMaterial {
|
||||||
|
material: Some(Box::new(Mirror::new(Color::new(1.0, 1.0, 1.0)))),
|
||||||
|
light: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
Box::new(s.clone()) as Box<dyn Scene<R> + Sync>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_pos(&self) -> Pos3 {
|
||||||
|
Pos3::new(-6.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_look_at(&self) -> Pos3 {
|
||||||
|
Pos3::new(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_up(&self) -> Dir3 {
|
||||||
|
Dir3::up()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_horizontal_fov(&self) -> Float {
|
||||||
|
Float::to_radians(90.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
||||||
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
||||||
use std::fmt::Debug;
|
use std::{cell::OnceCell, fmt::Debug};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
parse_obj::ObjData,
|
parse_obj::ObjData,
|
||||||
|
|
@ -10,42 +10,67 @@ use crate::{
|
||||||
|
|
||||||
use super::ExampleScene;
|
use super::ExampleScene;
|
||||||
|
|
||||||
pub fn scene<R: Rng + Debug + 'static>() -> ExampleScene<R> {
|
pub struct Cornell2<R: Rng> {
|
||||||
let f = || {
|
scene: OnceCell<TriangleBVH<R>>,
|
||||||
let obj = ObjData::new("ray-tracing-scene/obj/cornell_box.obj").unwrap();
|
}
|
||||||
|
|
||||||
let triangles = obj
|
impl<R: Rng> Cornell2<R> {
|
||||||
.triangle_faces()
|
pub fn new() -> Self {
|
||||||
.map(|t| Triangle::new(t.v, t.mat.unwrap()))
|
Self {
|
||||||
.collect();
|
scene: OnceCell::new(),
|
||||||
|
}
|
||||||
let materials = obj
|
}
|
||||||
.materials()
|
}
|
||||||
.iter()
|
|
||||||
.map(|m| match m.name.as_str() {
|
impl<R: Rng + 'static> ExampleScene<R> for Cornell2<R> {
|
||||||
"white" => BVHMaterial::new_material(DiffuseMaterial::new(Color::white())),
|
fn get_scene(&self) -> Box<dyn Scene<R> + Sync> {
|
||||||
"light" => BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
|
let s = self.scene.get_or_init(|| {
|
||||||
"blue" => {
|
let obj = ObjData::new("ray-tracing-scene/obj/cornell_box.obj").unwrap();
|
||||||
BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 0.0, 1.0)))
|
|
||||||
}
|
let triangles = obj
|
||||||
"red" => BVHMaterial::new_material(DiffuseMaterial::new(Color::new(1.0, 0.0, 0.0))),
|
.triangle_faces()
|
||||||
"green" => {
|
.map(|t| Triangle::new(t.v, t.mat.unwrap()))
|
||||||
BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 1.0, 0.0)))
|
.collect();
|
||||||
}
|
|
||||||
"mirror" => BVHMaterial::new_material(Mirror::new(Color::white())),
|
let materials = obj
|
||||||
_ => unreachable!(),
|
.materials()
|
||||||
})
|
.iter()
|
||||||
.collect();
|
.map(|m| match m.name.as_str() {
|
||||||
|
"white" => BVHMaterial::new_material(DiffuseMaterial::new(Color::white())),
|
||||||
let scene = TriangleBVH::new(obj.vertices, triangles, materials);
|
"light" => BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
|
||||||
Box::new(scene) as Box<dyn Scene<R> + Sync>
|
"blue" => {
|
||||||
};
|
BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 0.0, 1.0)))
|
||||||
|
}
|
||||||
ExampleScene {
|
"red" => {
|
||||||
scene: f,
|
BVHMaterial::new_material(DiffuseMaterial::new(Color::new(1.0, 0.0, 0.0)))
|
||||||
camera_pos: Pos3::new(275.0, 275.0, -800.0),
|
}
|
||||||
camera_look_at: Pos3::new(275.0, 275.0, 275.0),
|
"green" => {
|
||||||
camera_up: Dir3::up(),
|
BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 1.0, 0.0)))
|
||||||
horizontal_fov: 90.0_f32.to_radians(),
|
}
|
||||||
|
"mirror" => BVHMaterial::new_material(Mirror::new(Color::white())),
|
||||||
|
_ => unreachable!(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
TriangleBVH::new(obj.vertices, triangles, materials)
|
||||||
|
});
|
||||||
|
|
||||||
|
Box::new(s.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_pos(&self) -> Pos3 {
|
||||||
|
Pos3::new(275.0, 275.0, -800.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_look_at(&self) -> Pos3 {
|
||||||
|
Pos3::new(275.0, 275.0, 275.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_up(&self) -> Dir3 {
|
||||||
|
Dir3::up()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_horizontal_fov(&self) -> Float {
|
||||||
|
Float::to_radians(90.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,27 @@ use ray_tracing_core::{prelude::*, scene::Scene};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub struct ExampleScene<R: Rng> {
|
pub trait ExampleScene<R: Rng + 'static> {
|
||||||
pub scene: fn() -> Box<dyn Scene<R> + Sync>,
|
fn get_scene(&self) -> Box<dyn Scene<R> + Sync>;
|
||||||
pub camera_pos: Pos3,
|
|
||||||
pub camera_look_at: Pos3,
|
fn get_camera_pos(&self) -> Pos3;
|
||||||
pub camera_up: Dir3,
|
|
||||||
pub horizontal_fov: Float,
|
fn get_camera_look_at(&self) -> Pos3;
|
||||||
|
|
||||||
|
fn get_camera_up(&self) -> Dir3;
|
||||||
|
|
||||||
|
fn get_horizontal_fov(&self) -> Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn example_scenes<R: Rng + Debug + 'static>() -> HashMap<&'static str, fn() -> ExampleScene<R>>
|
pub fn example_scenes<R: Rng + Debug + 'static>() -> HashMap<&'static str, Box<dyn ExampleScene<R>>>
|
||||||
{
|
{
|
||||||
let mut map: HashMap<&str, fn() -> ExampleScene<R>> = HashMap::new();
|
let mut map: HashMap<&str, Box<dyn ExampleScene<R>>> = HashMap::new();
|
||||||
map.insert("basic_cornel", basic_cornell::scene::<R>);
|
map.insert("basic_cornel", Box::new(basic_cornell::BasicCornell::new()));
|
||||||
map.insert("cornel2", cornell2::scene::<R>);
|
map.insert("cornel2", Box::new(cornell2::Cornell2::new()));
|
||||||
map.insert("stanford_dragon", stanford_dragon::scene::<R>);
|
map.insert(
|
||||||
|
"stanford_dragon",
|
||||||
|
Box::new(stanford_dragon::StanfordDragon::new()),
|
||||||
|
);
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene};
|
||||||
use ray_tracing_material::{
|
use ray_tracing_material::{
|
||||||
diffuse::DiffuseMaterial,
|
|
||||||
microfacet::{BeckmannDistribution, Microfacet},
|
microfacet::{BeckmannDistribution, Microfacet},
|
||||||
oren_nayar::OrenNayar,
|
oren_nayar::OrenNayar,
|
||||||
};
|
};
|
||||||
use std::fmt::Debug;
|
use std::cell::OnceCell;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
parse_obj::ObjData,
|
parse_obj::ObjData,
|
||||||
|
|
@ -14,72 +13,95 @@ use crate::{
|
||||||
|
|
||||||
use super::ExampleScene;
|
use super::ExampleScene;
|
||||||
|
|
||||||
pub fn scene<R: Rng + Debug + 'static>() -> ExampleScene<R> {
|
pub struct StanfordDragon<R: Rng> {
|
||||||
let f = || {
|
scene: OnceCell<TriangleBVH<R>>,
|
||||||
let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap();
|
}
|
||||||
|
|
||||||
let mut triangles = obj
|
impl<R: Rng> StanfordDragon<R> {
|
||||||
.triangle_faces()
|
pub fn new() -> Self {
|
||||||
.map(|t| Triangle::new(t.v, 0))
|
Self {
|
||||||
.collect::<Vec<_>>();
|
scene: OnceCell::new(),
|
||||||
|
|
||||||
let color = Color::new(0.2, 0.2, 0.9);
|
|
||||||
let materials = vec![
|
|
||||||
BVHMaterial::new_material(Microfacet::new(BeckmannDistribution::new(0.01), color)),
|
|
||||||
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))),
|
|
||||||
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))),
|
|
||||||
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))),
|
|
||||||
BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut vertices = obj.vertices;
|
|
||||||
for v in &mut vertices {
|
|
||||||
*v = Pos3::new(v.x(), v.z() + 60.0, -v.y());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let side_length = 400.0;
|
}
|
||||||
let light_size = 150.0;
|
|
||||||
let light_offset = 0.01;
|
impl<R: Rng + 'static> ExampleScene<R> for StanfordDragon<R> {
|
||||||
let offset = vertices.len() as u32;
|
fn get_scene(&self) -> Box<dyn Scene<R> + Sync> {
|
||||||
vertices.extend_from_slice(&[
|
let s = self.scene.get_or_init(|| {
|
||||||
Pos3::new(side_length, 2.0 * side_length, side_length),
|
let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap();
|
||||||
Pos3::new(side_length, 2.0 * side_length, -side_length),
|
|
||||||
Pos3::new(side_length, 0.0, side_length),
|
let mut triangles = obj
|
||||||
Pos3::new(side_length, 0.0, -side_length),
|
.triangle_faces()
|
||||||
Pos3::new(-side_length, 2.0 * side_length, side_length),
|
.map(|t| Triangle::new(t.v, 0))
|
||||||
Pos3::new(-side_length, 2.0 * side_length, -side_length),
|
.collect::<Vec<_>>();
|
||||||
Pos3::new(-side_length, 0.0, side_length),
|
|
||||||
Pos3::new(-side_length, 0.0, -side_length),
|
let color = Color::new(0.2, 0.2, 0.9);
|
||||||
Pos3::new(light_size, 2.0 * side_length - light_offset, light_size),
|
let materials = vec![
|
||||||
Pos3::new(light_size, 2.0 * side_length - light_offset, -light_size),
|
BVHMaterial::new_material(Microfacet::new(BeckmannDistribution::new(0.01), color)),
|
||||||
Pos3::new(-light_size, 2.0 * side_length - light_offset, light_size),
|
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))),
|
||||||
Pos3::new(-light_size, 2.0 * side_length - light_offset, -light_size),
|
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))),
|
||||||
]);
|
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))),
|
||||||
|
BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
|
||||||
triangles.extend_from_slice(&[
|
];
|
||||||
Triangle::new([offset, 1 + offset, 2 + offset], 1),
|
|
||||||
Triangle::new([1 + offset, 3 + offset, 2 + offset], 1),
|
let mut vertices = obj.vertices;
|
||||||
Triangle::new([offset, 4 + offset, 1 + offset], 1),
|
for v in &mut vertices {
|
||||||
Triangle::new([1 + offset, 4 + offset, 5 + offset], 1),
|
*v = Pos3::new(v.x(), v.z() + 60.0, -v.y());
|
||||||
Triangle::new([2 + offset, 3 + offset, 6 + offset], 1),
|
}
|
||||||
Triangle::new([3 + offset, 7 + offset, 6 + offset], 1),
|
|
||||||
Triangle::new([offset, 2 + offset, 4 + offset], 2),
|
let side_length = 400.0;
|
||||||
Triangle::new([6 + offset, 4 + offset, 2 + offset], 2),
|
let light_size = 150.0;
|
||||||
Triangle::new([1 + offset, 5 + offset, 3 + offset], 3),
|
let light_offset = 0.01;
|
||||||
Triangle::new([7 + offset, 3 + offset, 5 + offset], 3),
|
let offset = vertices.len() as u32;
|
||||||
Triangle::new([8 + offset, 10 + offset, 9 + offset], 4),
|
vertices.extend_from_slice(&[
|
||||||
Triangle::new([11 + offset, 9 + offset, 10 + offset], 4),
|
Pos3::new(side_length, 2.0 * side_length, side_length),
|
||||||
]);
|
Pos3::new(side_length, 2.0 * side_length, -side_length),
|
||||||
|
Pos3::new(side_length, 0.0, side_length),
|
||||||
let scene = TriangleBVH::new(vertices, triangles, materials);
|
Pos3::new(side_length, 0.0, -side_length),
|
||||||
Box::new(scene) as Box<dyn Scene<R> + Sync>
|
Pos3::new(-side_length, 2.0 * side_length, side_length),
|
||||||
};
|
Pos3::new(-side_length, 2.0 * side_length, -side_length),
|
||||||
|
Pos3::new(-side_length, 0.0, side_length),
|
||||||
ExampleScene {
|
Pos3::new(-side_length, 0.0, -side_length),
|
||||||
scene: f,
|
Pos3::new(light_size, 2.0 * side_length - light_offset, light_size),
|
||||||
camera_pos: Pos3::new(-150.0, 160.0, 250.0),
|
Pos3::new(light_size, 2.0 * side_length - light_offset, -light_size),
|
||||||
camera_look_at: Pos3::new(0.0, 60.0, 0.0),
|
Pos3::new(-light_size, 2.0 * side_length - light_offset, light_size),
|
||||||
camera_up: Dir3::up(),
|
Pos3::new(-light_size, 2.0 * side_length - light_offset, -light_size),
|
||||||
horizontal_fov: 90.0_f32.to_radians(),
|
]);
|
||||||
|
|
||||||
|
triangles.extend_from_slice(&[
|
||||||
|
Triangle::new([offset, 1 + offset, 2 + offset], 1),
|
||||||
|
Triangle::new([1 + offset, 3 + offset, 2 + offset], 1),
|
||||||
|
Triangle::new([offset, 4 + offset, 1 + offset], 1),
|
||||||
|
Triangle::new([1 + offset, 4 + offset, 5 + offset], 1),
|
||||||
|
Triangle::new([2 + offset, 3 + offset, 6 + offset], 1),
|
||||||
|
Triangle::new([3 + offset, 7 + offset, 6 + offset], 1),
|
||||||
|
Triangle::new([offset, 2 + offset, 4 + offset], 2),
|
||||||
|
Triangle::new([6 + offset, 4 + offset, 2 + offset], 2),
|
||||||
|
Triangle::new([1 + offset, 5 + offset, 3 + offset], 3),
|
||||||
|
Triangle::new([7 + offset, 3 + offset, 5 + offset], 3),
|
||||||
|
Triangle::new([8 + offset, 10 + offset, 9 + offset], 4),
|
||||||
|
Triangle::new([11 + offset, 9 + offset, 10 + offset], 4),
|
||||||
|
]);
|
||||||
|
|
||||||
|
TriangleBVH::new(vertices, triangles, materials)
|
||||||
|
});
|
||||||
|
|
||||||
|
Box::new(s.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_pos(&self) -> Pos3 {
|
||||||
|
Pos3::new(-150.0, 160.0, 250.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_look_at(&self) -> Pos3 {
|
||||||
|
Pos3::new(0.0, 60.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_camera_up(&self) -> Dir3 {
|
||||||
|
Dir3::up()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_horizontal_fov(&self) -> Float {
|
||||||
|
Float::to_radians(90.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use ray_tracing_core::{
|
||||||
scene::{Intersection, LightSample, Scene},
|
scene::{Intersection, LightSample, Scene},
|
||||||
};
|
};
|
||||||
use sampling::sample_triangle;
|
use sampling::sample_triangle;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
type Index = u32;
|
type Index = u32;
|
||||||
|
|
||||||
|
|
@ -11,11 +12,23 @@ type Index = u32;
|
||||||
pub struct TriangleBVH<R: Rng> {
|
pub struct TriangleBVH<R: Rng> {
|
||||||
vertices: Vec<Pos3>,
|
vertices: Vec<Pos3>,
|
||||||
triangles: Vec<Triangle>,
|
triangles: Vec<Triangle>,
|
||||||
materials: Vec<BVHMaterial<R>>,
|
materials: Arc<[BVHMaterial<R>]>,
|
||||||
bvh: Vec<Node>,
|
bvh: Vec<Node>,
|
||||||
lights: Vec<Triangle>,
|
lights: Vec<Triangle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Rng> Clone for TriangleBVH<R> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
vertices: self.vertices.clone(),
|
||||||
|
triangles: self.triangles.clone(),
|
||||||
|
materials: Arc::clone(&self.materials),
|
||||||
|
bvh: self.bvh.clone(),
|
||||||
|
lights: self.lights.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BVHMaterial<R: Rng> {
|
pub struct BVHMaterial<R: Rng> {
|
||||||
pub material: Option<Box<dyn Material<R>>>,
|
pub material: Option<Box<dyn Material<R>>>,
|
||||||
|
|
@ -223,7 +236,7 @@ impl<R: Rng> TriangleBVH<R> {
|
||||||
vertices,
|
vertices,
|
||||||
bvh,
|
bvh,
|
||||||
triangles,
|
triangles,
|
||||||
materials,
|
materials: materials.into(),
|
||||||
lights,
|
lights,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,17 +97,17 @@ fn main() {
|
||||||
|
|
||||||
for scene in scenes {
|
for scene in scenes {
|
||||||
let f = map.get(scene).unwrap();
|
let f = map.get(scene).unwrap();
|
||||||
let e = f();
|
|
||||||
|
let s = f.get_scene();
|
||||||
|
|
||||||
let c = BasicCamera::from_look_at(
|
let c = BasicCamera::from_look_at(
|
||||||
args.width,
|
args.width,
|
||||||
args.height,
|
args.height,
|
||||||
e.camera_pos,
|
f.get_camera_pos(),
|
||||||
e.camera_look_at,
|
f.get_camera_look_at(),
|
||||||
e.camera_up,
|
f.get_camera_up(),
|
||||||
e.horizontal_fov,
|
f.get_horizontal_fov(),
|
||||||
);
|
);
|
||||||
let s = (e.scene)();
|
|
||||||
|
|
||||||
let r = DepthRenderer::new(args.width, args.height);
|
let r = DepthRenderer::new(args.width, args.height);
|
||||||
render_image(
|
render_image(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue