Add scene for presentation title.

This commit is contained in:
hal8174 2025-07-14 21:14:08 +02:00
parent 96e7085e37
commit 6e57187e3a
Signed by: hal8174
SSH key fingerprint: SHA256:JwuqS+eVfISfKr+DkDQ6NWAbGd1jFAHkPpCM1yCnlTs
3 changed files with 156 additions and 2 deletions

View file

@ -52,12 +52,18 @@ pub fn example_scenes<R: Rng + Debug + 'static>() -> HashMap<&'static str, Box<d
// let material = Iridescent::new(250.0, 250.0, 1.0, 1.3, 20); // let material = Iridescent::new(250.0, 250.0, 1.0, 1.3, 20);
let material = Iridescent::new(0.9 * 988.0, 0.1 * 988.0, 1.0, 1.5, 20); let material = Iridescent::new(0.9 * 988.0, 0.1 * 988.0, 1.0, 1.5, 20);
map.insert("sphere", Box::new(sphere::SphereScene::new(material))); map.insert("sphere", Box::new(sphere::SphereScene::new(material)));
map.insert(
"presentation",
Box::new(presentation_title_image::Presentation::new()),
);
map map
} }
pub mod basic_cornell; pub mod basic_cornell;
pub mod cornell2; pub mod cornell2;
pub mod mis_test; pub mod mis_test;
pub mod presentation_title_image;
pub mod sphere; pub mod sphere;
pub mod stanford_dragon; pub mod stanford_dragon;
pub mod stanford_dragon_as; pub mod stanford_dragon_as;

View file

@ -0,0 +1,148 @@
use crate::{
parse_obj::ObjData,
triangle_bvh::{BVHMaterial, Triangle, TriangleBVH},
};
use rand::Rng;
use ray_tracing_core::{
color::Color,
light::AreaLight,
math::{Dir3, Pos3},
prelude::Float,
};
use ray_tracing_material::{iridescent::Iridescent, oren_nayar::OrenNayar};
use std::cell::OnceCell;
use super::ExampleScene;
#[derive(Default)]
pub struct Presentation<R: Rng> {
scene: OnceCell<TriangleBVH<R>>,
}
impl<R: Rng> Presentation<R> {
pub fn new() -> Self {
Self {
scene: OnceCell::new(),
}
}
}
impl<R: Rng + 'static> ExampleScene<R> for Presentation<R> {
fn get_scene(&self) -> Box<dyn ray_tracing_core::scene::Scene<R> + Sync> {
let s = self.scene.get_or_init(|| {
let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap();
let mut triangles = obj
.triangle_faces()
.map(|t| Triangle::new(t.v, 4))
.collect::<Vec<_>>();
let materials = vec![
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.2, 0.2))),
BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.2, 0.9, 0.2))),
BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
BVHMaterial::new_material(Iridescent::new(250.0, 250.0, 1.0, 1.5, 20)),
BVHMaterial::new_material(Iridescent::new(0.9 * 988.0, 0.1 * 988.0, 1.0, 1.5, 20)),
BVHMaterial::new_material(Iridescent::new(0.1 * 500.0, 0.9 * 500.0, 1.0, 1.5, 20)),
];
let dragon_vertices = obj.vertices.len();
let dragon_triangles = triangles.len();
let mut vertices = obj.vertices;
for v in &mut vertices {
*v = Pos3::new(v.x() * 0.3, (v.z() + 60.0) * 0.3, -v.y() * 0.3);
}
// second dragon
let offset = vertices.len() as u32;
for i in 0..dragon_vertices {
vertices.push(vertices[i] + Dir3::new(50.0, 0.0, 25.0));
}
for i in 0..dragon_triangles {
triangles.push(Triangle::new(
[
triangles[i].vertices[0] + offset,
triangles[i].vertices[1] + offset,
triangles[i].vertices[2] + offset,
],
5,
));
}
// third dragon
let offset = vertices.len() as u32;
for i in 0..dragon_vertices {
vertices.push(vertices[i] + Dir3::new(-50.0, 0.0, -25.0));
}
for i in 0..dragon_triangles {
triangles.push(Triangle::new(
[
triangles[i].vertices[0] + offset,
triangles[i].vertices[1] + offset,
triangles[i].vertices[2] + offset,
],
6,
));
}
// cornel box
let side_length = 400.0;
let light_size = 150.0;
let light_offset = 0.01;
let offset = vertices.len() as u32;
vertices.extend_from_slice(&[
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),
Pos3::new(side_length, 0.0, -side_length),
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),
Pos3::new(-side_length, 0.0, -side_length),
Pos3::new(light_size, 2.0 * side_length - light_offset, light_size),
Pos3::new(light_size, 2.0 * side_length - light_offset, -light_size),
Pos3::new(-light_size, 2.0 * side_length - light_offset, light_size),
Pos3::new(-light_size, 2.0 * side_length - light_offset, -light_size),
]);
triangles.extend_from_slice(&[
Triangle::new([offset, 1 + offset, 2 + offset], 0),
Triangle::new([1 + offset, 3 + offset, 2 + offset], 0),
Triangle::new([offset, 4 + offset, 1 + offset], 0),
Triangle::new([1 + offset, 4 + offset, 5 + offset], 0),
Triangle::new([2 + offset, 3 + offset, 6 + offset], 0),
Triangle::new([3 + offset, 7 + offset, 6 + offset], 0),
Triangle::new([offset, 2 + offset, 4 + offset], 1),
Triangle::new([6 + offset, 4 + offset, 2 + offset], 1),
Triangle::new([1 + offset, 5 + offset, 3 + offset], 2),
Triangle::new([7 + offset, 3 + offset, 5 + offset], 2),
Triangle::new([8 + offset, 10 + offset, 9 + offset], 3),
Triangle::new([11 + offset, 9 + offset, 10 + offset], 3),
]);
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, 15.0, 0.0)
}
fn get_camera_up(&self) -> Dir3 {
Dir3::up()
}
fn get_horizontal_fov(&self) -> Float {
Float::to_radians(90.0)
}
}

View file

@ -84,8 +84,8 @@ enum Node {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Triangle { pub struct Triangle {
vertices: [Index; 3], pub vertices: [Index; 3],
material: Index, pub material: Index,
} }
impl Triangle { impl Triangle {