///|
/// Advanced demo scenes for moon-ray.
/// Visually impressive scenes demonstrating the renderer's capabilities.
pub fn mirror_corridor_scene() -> (HitableList, Camera) {
let mut world = HitableList::new()
let silver = Material::Metal(Vec3::new(x=0.95, y=0.95, z=0.95), 0.0)
let gold = Material::Metal(Vec3::new(x=0.95, y=0.65, z=0.15), 0.02)
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=-0.5, z=0.0),
normal=Vec3::new(x=0.0, y=1.0, z=0.0),
material=Material::Textured(Texture::Checker(
Texture::Solid(Vec3::new(x=0.05, y=0.05, z=0.1)),
Texture::Solid(Vec3::new(x=0.02, y=0.02, z=0.05)),
8.0,
)),
)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=3.0, z=0.0),
normal=Vec3::new(x=0.0, y=-1.0, z=0.0),
material=silver,
)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=-3.0, y=1.0, z=0.0),
normal=Vec3::new(x=1.0, y=0.0, z=0.0),
material=silver,
)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=3.0, y=1.0, z=0.0),
normal=Vec3::new(x=-1.0, y=0.0, z=0.0),
material=silver,
)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=1.0, z=-5.0),
normal=Vec3::new(x=0.0, y=0.0, z=1.0),
material=silver,
)))
for row in 0..<5 {
for col in 0..<3 {
let x = (-2.0) + col.to_double() * 2.0
let z = (-2.0) - row.to_double() * 0.8
let y = 0.0 + (row.to_double() * 0.2)
world = world.add(Hitable::Sphere(Sphere::new(
center=Vec3::new(x=x, y=y, z=z),
radius=0.18 + row.to_double() * 0.02,
material=if (row + col) % 2 == 0 { gold } else { silver },
)))
}
}
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=0.0, y=2.8, z=-1.5),
normal=Vec3::new(x=0.0, y=-1.0, z=0.0),
radius=1.2,
material=Material::DiffuseLight(Texture::Solid(Vec3::new(x=15.0, y=13.0, z=10.0))),
)))
let cam = Camera::new(
lookfrom=Vec3::new(x=0.0, y=1.2, z=2.5),
lookat=Vec3::new(x=0.0, y=0.5, z=-1.5),
vup=Vec3::new(x=0.0, y=1.0, z=0.0),
vfov=55.0, aspect_ratio=16.0 / 9.0,
aperture=0.02, focus_dist=3.0,
time0=0.0, time1=0.0,
)
(world, cam)
}
pub fn crystal_garden_scene() -> (HitableList, Camera) {
let mut world = HitableList::new()
let dark = Material::Lambertian(Vec3::new(x=0.02, y=0.02, z=0.03))
let warm_light = Material::DiffuseLight(Texture::Solid(Vec3::new(x=20.0, y=16.0, z=10.0)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=-1.5, z=0.0),
normal=Vec3::new(x=0.0, y=1.0, z=0.0),
material=dark,
)))
let glass = Material::Dielectric(1.52)
let blue_glass = Material::Dielectric(1.45)
let water = Material::Dielectric(1.33)
let diamond = Material::Dielectric(2.42)
world = world.add(Hitable::Sphere(Sphere::new(
center=Vec3::new(x=-2.5, y=0.4, z=-2.0),
radius=0.5, material=diamond,
)))
world = world.add(Hitable::BoxShape(BoxShape::new(
center=Vec3::new(x=-1.2, y=0.25, z=-1.5),
size=Vec3::new(x=0.5, y=0.5, z=0.5),
material=glass,
)))
world = world.add(Hitable::Cylinder(Cylinder::new(
center=Vec3::new(x=0.0, y=0.0, z=-2.5),
radius=0.25, height=1.8,
material=blue_glass,
)))
world = world.add(Hitable::Cone(Cone::new(
base_center=Vec3::new(x=1.5, y=-0.3, z=-1.8),
base_radius=0.4, height=1.5,
material=water,
)))
world = world.add(Hitable::Torus(Torus::new(
center=Vec3::new(x=2.8, y=0.3, z=-2.2),
major_radius=0.35, minor_radius=0.12,
material=glass,
)))
for i in 0..<8 {
let angle = i.to_double() / 8.0 * 2.0 * @math.PI
let r = 3.5
let x = r * @math.cos(angle)
let z = r * @math.sin(angle) - 1.0
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=x, y=3.5, z=z),
normal=Vec3::new(x=-x/r, y=-0.3, z=-z/r),
radius=0.25,
material=if i % 2 == 0 {
warm_light
} else {
Material::DiffuseLight(Texture::Solid(Vec3::new(x=10.0, y=20.0, z=25.0)))
},
)))
}
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=0.0, y=4.0, z=-1.0),
normal=Vec3::new(x=0.0, y=-1.0, z=0.0),
radius=1.0,
material=warm_light,
)))
let cam = Camera::new(
lookfrom=Vec3::new(x=0.0, y=2.0, z=5.0),
lookat=Vec3::new(x=0.0, y=0.3, z=-2.0),
vup=Vec3::new(x=0.0, y=1.0, z=0.0),
vfov=45.0, aspect_ratio=16.0 / 9.0,
aperture=0.03, focus_dist=6.0,
time0=0.0, time1=0.0,
)
(world, cam)
}
pub fn sunrise_valley_scene() -> (HitableList, Camera) {
let mut world = HitableList::new()
let grass = Material::Lambertian(Vec3::new(x=0.15, y=0.45, z=0.1))
let stone = Material::Lambertian(Vec3::new(x=0.45, y=0.4, z=0.35))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=-5.0, z=0.0),
normal=Vec3::new(x=0.0, y=1.0, z=0.0),
material=Material::Textured(Texture::Checker(
Texture::Solid(Vec3::new(x=0.12, y=0.4, z=0.08)),
Texture::Solid(Vec3::new(x=0.18, y=0.5, z=0.12)),
0.5,
)),
)))
let rng1 = new_rng(123UL)
for _i in 0..<40 {
let (ang, r1) = rng1.random_double_range(min=0.0, max=2.0 * @math.PI)
let (rad, r2) = r1.random_double_range(min=5.0, max=20.0)
let (sx, r3) = r2.random_double_range(min=0.3, max=1.5)
let (sz, _) = r3.random_double_range(min=0.3, max=1.5)
let x = rad * @math.cos(ang)
let z = rad * @math.sin(ang)
let h = 0.5 + (rad / 20.0) * 3.0
world = world.add(Hitable::BoxShape(BoxShape::new(
center=Vec3::new(x=x, y=-5.0 + h/2.0, z=z),
size=Vec3::new(x=sx, y=h, z=sz),
material=stone,
)))
}
for _j in 0..<15 {
let (ang2, r4) = rng1.random_double_range(min=0.0, max=2.0 * @math.PI)
let (rad2, r5) = r4.random_double_range(min=4.0, max=12.0)
let (size2, _) = r5.random_double_range(min=0.2, max=0.5)
let x = rad2 * @math.cos(ang2)
let z = rad2 * @math.sin(ang2)
world = world.add(Hitable::Sphere(Sphere::new(
center=Vec3::new(x=x, y=-4.5, z=z),
radius=size2,
material=grass,
)))
}
world = world.add(Hitable::Sphere(Sphere::new(
center=Vec3::new(x=2.0, y=0.3, z=-3.0),
radius=1.0,
material=Material::Metal(Vec3::new(x=0.95, y=0.85, z=0.7), 0.02),
)))
world = world.add(Hitable::Sphere(Sphere::new(
center=Vec3::new(x=-3.0, y=0.6, z=-5.0),
radius=1.5,
material=Material::Dielectric(1.5),
)))
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=10.0, y=8.0, z=-12.0),
normal=Vec3::new(x=-0.5, y=-0.6, z=0.6),
radius=5.0,
material=Material::DiffuseLight(Texture::Solid(Vec3::new(x=30.0, y=20.0, z=8.0))),
)))
let cam = Camera::new(
lookfrom=Vec3::new(x=0.0, y=1.5, z=4.0),
lookat=Vec3::new(x=0.0, y=0.0, z=-4.0),
vup=Vec3::new(x=0.0, y=1.0, z=0.0),
vfov=60.0, aspect_ratio=16.0 / 9.0,
aperture=0.05, focus_dist=6.0,
time0=0.0, time1=0.0,
)
(world, cam)
}
pub fn prism_lab_scene() -> (HitableList, Camera) {
let mut world = HitableList::new()
let white = Material::Lambertian(Vec3::new(x=0.85, y=0.85, z=0.85))
let black = Material::Lambertian(Vec3::new(x=0.03, y=0.03, z=0.03))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=-1.0, z=0.0),
normal=Vec3::new(x=0.0, y=1.0, z=0.0),
material=black,
)))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=0.0, z=-6.0),
normal=Vec3::new(x=0.0, y=0.0, z=1.0),
material=white,
)))
for i in 0..<6 {
let x = (-2.5) + i.to_double() * 1.0
let ior_list = [1.33, 1.45, 1.52, 1.62, 1.77, 2.42]
let ior = ior_list[i]
let mat = Material::Dielectric(ior)
let h = 0.5 + i.to_double() * 0.2
world = world.add(Hitable::Cone(Cone::new(
base_center=Vec3::new(x=x, y=-1.0, z=-3.5),
base_radius=0.25 + i.to_double() * 0.03,
height=h,
material=mat,
)))
world = world.add(Hitable::BoxShape(BoxShape::new(
center=Vec3::new(x=x, y=-0.7 + h/4.0, z=-2.0),
size=Vec3::new(x=0.2, y=0.3, z=0.2),
material=mat,
)))
}
let colors = [
Vec3::new(x=1.0, y=0.2, z=0.2),
Vec3::new(x=0.2, y=1.0, z=0.2),
Vec3::new(x=0.2, y=0.2, z=1.0),
Vec3::new(x=1.0, y=1.0, z=0.2),
Vec3::new(x=1.0, y=0.2, z=1.0),
Vec3::new(x=0.2, y=1.0, z=1.0),
]
for i in 0..<6 {
let x = (-2.5) + i.to_double() * 1.0
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=x, y=3.0, z=-3.0),
normal=Vec3::new(x=0.0, y=-1.0, z=0.1),
radius=0.2,
material=Material::DiffuseLight(Texture::Solid(colors[i].mul_scalar(12.0))),
)))
}
let cam = Camera::new(
lookfrom=Vec3::new(x=0.0, y=1.2, z=2.5),
lookat=Vec3::new(x=0.0, y=0.0, z=-3.0),
vup=Vec3::new(x=0.0, y=1.0, z=0.0),
vfov=50.0, aspect_ratio=16.0 / 9.0,
aperture=0.02, focus_dist=4.0,
time0=0.0, time1=0.0,
)
(world, cam)
}
pub fn city_at_night_scene() -> (HitableList, Camera) {
let mut world = HitableList::new()
let concrete = Material::Lambertian(Vec3::new(x=0.35, y=0.35, z=0.38))
let glass_blue = Material::Metal(Vec3::new(x=0.3, y=0.4, z=0.7), 0.05)
let glass_gold = Material::Metal(Vec3::new(x=0.8, y=0.6, z=0.3), 0.03)
let dark_ground = Material::Lambertian(Vec3::new(x=0.05, y=0.05, z=0.08))
world = world.add(Hitable::Plane(Plane::new(
center=Vec3::new(x=0.0, y=-1.0, z=0.0),
normal=Vec3::new(x=0.0, y=1.0, z=0.0),
material=dark_ground,
)))
let w_rng = new_rng(456UL)
for i in 0..<30 {
let (xoff, r1) = w_rng.random_double_range(min=-0.3, max=0.3)
let (zoff, r2) = r1.random_double_range(min=-0.3, max=0.3)
let (h, r3) = r2.random_double_range(min=0.5, max=2.5)
let (w, _) = r3.random_double_range(min=0.3, max=0.8)
let grid_x = (i % 6).to_double() - 2.5
let grid_z = (i / 6).to_double() - 2.5
let x = grid_x * 1.5 + xoff
let z = grid_z * 1.8 + zoff
let mat = if i % 3 == 0 { glass_blue }
else if i % 3 == 1 { glass_gold }
else { concrete }
world = world.add(Hitable::BoxShape(BoxShape::new(
center=Vec3::new(x=x, y=-1.0 + h/2.0, z=z-3.0),
size=Vec3::new(x=w, y=h, z=w),
material=mat,
)))
if i % 4 == 0 {
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=x, y=-0.3 + h/2.0, z=z-3.0 + w/2.0 + 0.01),
normal=Vec3::new(x=0.0, y=0.0, z=-1.0),
radius=w * 0.15,
material=Material::Emissive(Vec3::new(x=5.0, y=3.0, z=1.5)),
)))
}
if i % 7 == 0 {
world = world.add(Hitable::Disk(Disk::new(
center=Vec3::new(x=x, y=-0.8 + h/2.0, z=z-3.0 + w/2.0 + 0.01),
normal=Vec3::new(x=0.0, y=0.0, z=-1.0),
radius=w * 0.12,
material=Material::Emissive(Vec3::new(x=2.0, y=4.0, z=8.0)),
)))
}
}
let cam = Camera::new(
lookfrom=Vec3::new(x=0.0, y=1.5, z=2.0),
lookat=Vec3::new(x=0.0, y=-0.2, z=-4.0),
vup=Vec3::new(x=0.0, y=1.0, z=0.0),
vfov=65.0, aspect_ratio=16.0 / 9.0,
aperture=0.05, focus_dist=5.0,
time0=0.0, time1=0.0,
)
(world, cam)
}