De-boxed many uses of Hit and Material.
Use of generic parameter directly where possible in structures instead of Box'd values. Added Material implementations for Box<Material> and Arc<Material> to aid in the automatic conversion when necessary to use a Sized value for Material. Implement From trait for [f32;3] to Vec3 to make some APIs Into<Vec3> which is a bit nicer to use.
This commit is contained in:
parent
7684bb2088
commit
36b2fba5b7
@ -246,14 +246,12 @@ mod tests {
|
|||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
0.1, 0.2, 0.5,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., 0.),
|
Vec3::new(1., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
0.,
|
0.,
|
||||||
@ -274,19 +272,17 @@ mod tests {
|
|||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
0.1, 0.2, 0.5,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., 0.),
|
Vec3::new(1., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 1., 0.),
|
Vec3::new(0., 1., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
0.,
|
0.,
|
||||||
|
|||||||
@ -19,9 +19,7 @@ pub struct Cuboid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cuboid {
|
impl Cuboid {
|
||||||
pub fn new(p_min: Vec3, p_max: Vec3, material: Box<Material>) -> Cuboid {
|
pub fn new(p_min: Vec3, p_max: Vec3, material: Arc<Material>) -> Cuboid {
|
||||||
let material = Arc::new(material);
|
|
||||||
|
|
||||||
Cuboid {
|
Cuboid {
|
||||||
p_min,
|
p_min,
|
||||||
p_max,
|
p_max,
|
||||||
@ -32,48 +30,48 @@ impl Cuboid {
|
|||||||
p_min.y,
|
p_min.y,
|
||||||
p_max.y,
|
p_max.y,
|
||||||
p_max.z,
|
p_max.z,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)),
|
)),
|
||||||
Box::new(FlipNormals::new(Box::new(XYRect::new(
|
Box::new(FlipNormals::new(XYRect::new(
|
||||||
p_min.x,
|
p_min.x,
|
||||||
p_max.x,
|
p_max.x,
|
||||||
p_min.y,
|
p_min.y,
|
||||||
p_max.y,
|
p_max.y,
|
||||||
p_min.z,
|
p_min.z,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)))),
|
))),
|
||||||
Box::new(XZRect::new(
|
Box::new(XZRect::new(
|
||||||
p_min.x,
|
p_min.x,
|
||||||
p_max.x,
|
p_max.x,
|
||||||
p_min.z,
|
p_min.z,
|
||||||
p_max.z,
|
p_max.z,
|
||||||
p_max.y,
|
p_max.y,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)),
|
)),
|
||||||
Box::new(FlipNormals::new(Box::new(XZRect::new(
|
Box::new(FlipNormals::new(XZRect::new(
|
||||||
p_min.x,
|
p_min.x,
|
||||||
p_max.x,
|
p_max.x,
|
||||||
p_min.z,
|
p_min.z,
|
||||||
p_max.z,
|
p_max.z,
|
||||||
p_min.y,
|
p_min.y,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)))),
|
))),
|
||||||
Box::new(YZRect::new(
|
Box::new(YZRect::new(
|
||||||
p_min.y,
|
p_min.y,
|
||||||
p_max.y,
|
p_max.y,
|
||||||
p_min.z,
|
p_min.z,
|
||||||
p_max.z,
|
p_max.z,
|
||||||
p_max.x,
|
p_max.x,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)),
|
)),
|
||||||
Box::new(FlipNormals::new(Box::new(YZRect::new(
|
Box::new(FlipNormals::new(YZRect::new(
|
||||||
p_min.y,
|
p_min.y,
|
||||||
p_max.y,
|
p_max.y,
|
||||||
p_min.z,
|
p_min.z,
|
||||||
p_max.z,
|
p_max.z,
|
||||||
p_min.x,
|
p_min.x,
|
||||||
Box::new(Arc::clone(&material)),
|
Arc::clone(&material),
|
||||||
)))),
|
))),
|
||||||
]),
|
]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,17 +3,26 @@ use hitable::Hit;
|
|||||||
use hitable::HitRecord;
|
use hitable::HitRecord;
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
|
|
||||||
pub struct FlipNormals {
|
pub struct FlipNormals<H>
|
||||||
hitable: Box<Hit>,
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
hitable: H,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlipNormals {
|
impl<H> FlipNormals<H>
|
||||||
pub fn new(hitable: Box<Hit>) -> FlipNormals {
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
pub fn new(hitable: H) -> FlipNormals<H> {
|
||||||
FlipNormals { hitable }
|
FlipNormals { hitable }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for FlipNormals {
|
impl<H> Hit for FlipNormals<H>
|
||||||
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
if let Some(rec) = self.hitable.hit(r, t_min, t_max) {
|
if let Some(rec) = self.hitable.hit(r, t_min, t_max) {
|
||||||
return Some(HitRecord {
|
return Some(HitRecord {
|
||||||
|
|||||||
@ -38,7 +38,7 @@ pub trait Material: Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material for Arc<Box<Material>> {
|
impl Material for Arc<Material> {
|
||||||
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
||||||
(**self).scatter(r_in, rec)
|
(**self).scatter(r_in, rec)
|
||||||
}
|
}
|
||||||
@ -47,18 +47,36 @@ impl Material for Arc<Box<Material>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Lambertian {
|
impl Material for Box<Material> {
|
||||||
// TODO(wathiede): implement texture sharing via references
|
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
||||||
albedo: Box<Texture>,
|
(**self).scatter(r_in, rec)
|
||||||
|
}
|
||||||
|
fn emitted(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||||
|
(**self).emitted(u, v, p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lambertian {
|
pub struct Lambertian<T>
|
||||||
pub fn new(texture: Box<Texture>) -> Lambertian {
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
|
// TODO(wathiede): implement texture sharing via references
|
||||||
|
albedo: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Lambertian<T>
|
||||||
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
|
pub fn new(texture: T) -> Lambertian<T> {
|
||||||
Lambertian { albedo: texture }
|
Lambertian { albedo: texture }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material for Lambertian {
|
impl<T> Material for Lambertian<T>
|
||||||
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
||||||
let target = rec.p + rec.normal + random_in_unit_sphere();
|
let target = rec.p + rec.normal + random_in_unit_sphere();
|
||||||
let (u, v) = rec.uv;
|
let (u, v) = rec.uv;
|
||||||
@ -164,17 +182,26 @@ impl Material for Dielectric {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DiffuseLight {
|
pub struct DiffuseLight<T>
|
||||||
emit: Box<Texture>,
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
|
emit: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiffuseLight {
|
impl<T> DiffuseLight<T>
|
||||||
pub fn new(emit: Box<Texture>) -> DiffuseLight {
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
|
pub fn new(emit: T) -> DiffuseLight<T> {
|
||||||
DiffuseLight { emit }
|
DiffuseLight { emit }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material for DiffuseLight {
|
impl<T> Material for DiffuseLight<T>
|
||||||
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
fn scatter(&self, _r_in: &Ray, _rec: &HitRecord) -> ScatterResponse {
|
fn scatter(&self, _r_in: &Ray, _rec: &HitRecord) -> ScatterResponse {
|
||||||
ScatterResponse {
|
ScatterResponse {
|
||||||
scattered: Default::default(),
|
scattered: Default::default(),
|
||||||
|
|||||||
@ -8,24 +8,30 @@ use sphere::get_sphere_uv;
|
|||||||
use vec3::dot;
|
use vec3::dot;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub struct MovingSphere {
|
pub struct MovingSphere<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
center0: Vec3,
|
center0: Vec3,
|
||||||
center1: Vec3,
|
center1: Vec3,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
time0: f32,
|
time0: f32,
|
||||||
time1: f32,
|
time1: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MovingSphere {
|
impl<M> MovingSphere<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
center0: Vec3,
|
center0: Vec3,
|
||||||
center1: Vec3,
|
center1: Vec3,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
time0: f32,
|
time0: f32,
|
||||||
time1: f32,
|
time1: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
) -> MovingSphere {
|
) -> MovingSphere<M> {
|
||||||
MovingSphere {
|
MovingSphere {
|
||||||
center0,
|
center0,
|
||||||
center1,
|
center1,
|
||||||
@ -41,7 +47,10 @@ impl MovingSphere {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for MovingSphere {
|
impl<M> Hit for MovingSphere<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t0: f32, t1: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t0: f32, t1: f32) -> Option<HitRecord> {
|
||||||
let oc = r.origin - self.center(r.time);
|
let oc = r.origin - self.center(r.time);
|
||||||
let a = dot(r.direction, r.direction);
|
let a = dot(r.direction, r.direction);
|
||||||
@ -58,7 +67,7 @@ impl Hit for MovingSphere {
|
|||||||
uv,
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center(r.time)) / self.radius,
|
normal: (point - self.center(r.time)) / self.radius,
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
||||||
@ -70,7 +79,7 @@ impl Hit for MovingSphere {
|
|||||||
uv,
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center(r.time)) / self.radius,
|
normal: (point - self.center(r.time)) / self.radius,
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,17 +5,23 @@ use material::Material;
|
|||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub struct XYRect {
|
pub struct XYRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
x0: f32,
|
x0: f32,
|
||||||
x1: f32,
|
x1: f32,
|
||||||
y0: f32,
|
y0: f32,
|
||||||
y1: f32,
|
y1: f32,
|
||||||
k: f32,
|
k: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XYRect {
|
impl<M> XYRect<M>
|
||||||
pub fn new(x0: f32, x1: f32, y0: f32, y1: f32, k: f32, material: Box<Material>) -> XYRect {
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
|
pub fn new(x0: f32, x1: f32, y0: f32, y1: f32, k: f32, material: M) -> XYRect<M> {
|
||||||
XYRect {
|
XYRect {
|
||||||
x0,
|
x0,
|
||||||
x1,
|
x1,
|
||||||
@ -27,7 +33,10 @@ impl XYRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for XYRect {
|
impl<M> Hit for XYRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let t = (self.k - r.origin.z) / r.direction.z;
|
let t = (self.k - r.origin.z) / r.direction.z;
|
||||||
if t < t_min || t > t_max {
|
if t < t_min || t > t_max {
|
||||||
@ -45,7 +54,7 @@ impl Hit for XYRect {
|
|||||||
uv: (u, v),
|
uv: (u, v),
|
||||||
p: r.point_at_parameter(t),
|
p: r.point_at_parameter(t),
|
||||||
normal: Vec3::new(0., 0., 1.),
|
normal: Vec3::new(0., 0., 1.),
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,17 +66,23 @@ impl Hit for XYRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct XZRect {
|
pub struct XZRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
x0: f32,
|
x0: f32,
|
||||||
x1: f32,
|
x1: f32,
|
||||||
z0: f32,
|
z0: f32,
|
||||||
z1: f32,
|
z1: f32,
|
||||||
k: f32,
|
k: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XZRect {
|
impl<M> XZRect<M>
|
||||||
pub fn new(x0: f32, x1: f32, z0: f32, z1: f32, k: f32, material: Box<Material>) -> XZRect {
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
|
pub fn new(x0: f32, x1: f32, z0: f32, z1: f32, k: f32, material: M) -> XZRect<M> {
|
||||||
XZRect {
|
XZRect {
|
||||||
x0,
|
x0,
|
||||||
x1,
|
x1,
|
||||||
@ -79,7 +94,10 @@ impl XZRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for XZRect {
|
impl<M> Hit for XZRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let t = (self.k - r.origin.y) / r.direction.y;
|
let t = (self.k - r.origin.y) / r.direction.y;
|
||||||
if t < t_min || t > t_max {
|
if t < t_min || t > t_max {
|
||||||
@ -97,7 +115,7 @@ impl Hit for XZRect {
|
|||||||
uv: (u, v),
|
uv: (u, v),
|
||||||
p: r.point_at_parameter(t),
|
p: r.point_at_parameter(t),
|
||||||
normal: Vec3::new(0., 1., 0.),
|
normal: Vec3::new(0., 1., 0.),
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,17 +127,23 @@ impl Hit for XZRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct YZRect {
|
pub struct YZRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
y0: f32,
|
y0: f32,
|
||||||
y1: f32,
|
y1: f32,
|
||||||
k: f32,
|
k: f32,
|
||||||
z0: f32,
|
z0: f32,
|
||||||
z1: f32,
|
z1: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YZRect {
|
impl<M> YZRect<M>
|
||||||
pub fn new(y0: f32, y1: f32, z0: f32, z1: f32, k: f32, material: Box<Material>) -> YZRect {
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
|
pub fn new(y0: f32, y1: f32, z0: f32, z1: f32, k: f32, material: M) -> YZRect<M> {
|
||||||
YZRect {
|
YZRect {
|
||||||
y0,
|
y0,
|
||||||
y1,
|
y1,
|
||||||
@ -131,7 +155,10 @@ impl YZRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for YZRect {
|
impl<M> Hit for YZRect<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let t = (self.k - r.origin.x) / r.direction.x;
|
let t = (self.k - r.origin.x) / r.direction.x;
|
||||||
if t < t_min || t > t_max {
|
if t < t_min || t > t_max {
|
||||||
@ -149,7 +176,7 @@ impl Hit for YZRect {
|
|||||||
uv: (u, v),
|
uv: (u, v),
|
||||||
p: r.point_at_parameter(t),
|
p: r.point_at_parameter(t),
|
||||||
normal: Vec3::new(1., 0., 0.),
|
normal: Vec3::new(1., 0., 0.),
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,7 +79,7 @@ pub struct Opt {
|
|||||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||||
pub subsamples: usize,
|
pub subsamples: usize,
|
||||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box"
|
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box"
|
||||||
#[structopt(long = "model", default_value = "cornell_box")]
|
#[structopt(long = "model", default_value = "book")]
|
||||||
pub model: Model,
|
pub model: Model,
|
||||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||||
#[structopt(long = "pprof", parse(from_os_str))]
|
#[structopt(long = "pprof", parse(from_os_str))]
|
||||||
|
|||||||
@ -8,15 +8,21 @@ use hitable::HitRecord;
|
|||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub struct RotateY {
|
pub struct RotateY<H>
|
||||||
hitable: Box<Hit>,
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
hitable: H,
|
||||||
sin_theta: f32,
|
sin_theta: f32,
|
||||||
cos_theta: f32,
|
cos_theta: f32,
|
||||||
bbox: Option<AABB>,
|
bbox: Option<AABB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RotateY {
|
impl<H> RotateY<H>
|
||||||
pub fn new(hitable: Box<Hit>, angle: f32) -> RotateY {
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
pub fn new(hitable: H, angle: f32) -> RotateY<H> {
|
||||||
let radians = PI / 180. * angle;
|
let radians = PI / 180. * angle;
|
||||||
let sin_theta = radians.sin();
|
let sin_theta = radians.sin();
|
||||||
let cos_theta = radians.cos();
|
let cos_theta = radians.cos();
|
||||||
@ -55,7 +61,10 @@ impl RotateY {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for RotateY {
|
impl<H> Hit for RotateY<H>
|
||||||
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let origin = Vec3::new(
|
let origin = Vec3::new(
|
||||||
self.cos_theta * r.origin[0] - self.sin_theta * r.origin[2],
|
self.cos_theta * r.origin[0] - self.sin_theta * r.origin[2],
|
||||||
|
|||||||
@ -46,9 +46,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
grid.push(Box::new(Sphere::new(
|
grid.push(Box::new(Sphere::new(
|
||||||
Vec3::new(x_pos, 0., z_pos),
|
Vec3::new(x_pos, 0., z_pos),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(r, g, b))),
|
||||||
r, g, b,
|
|
||||||
))))),
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,13 +7,13 @@ use hitable_list::HitableList;
|
|||||||
use kdtree::KDTree;
|
use kdtree::KDTree;
|
||||||
use material::Dielectric;
|
use material::Dielectric;
|
||||||
use material::Lambertian;
|
use material::Lambertian;
|
||||||
|
use material::Material;
|
||||||
use material::Metal;
|
use material::Metal;
|
||||||
use renderer::Opt;
|
use renderer::Opt;
|
||||||
use renderer::Scene;
|
use renderer::Scene;
|
||||||
use sphere::Sphere;
|
use sphere::Sphere;
|
||||||
use texture::CheckerTexture;
|
use texture::CheckerTexture;
|
||||||
use texture::ConstantTexture;
|
use texture::ConstantTexture;
|
||||||
use texture::Texture;
|
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub fn new(opt: &Opt) -> Scene {
|
pub fn new(opt: &Opt) -> Scene {
|
||||||
@ -35,9 +35,9 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
time_max,
|
time_max,
|
||||||
);
|
);
|
||||||
let ground_color = if opt.use_accel {
|
let ground_color = if opt.use_accel {
|
||||||
Vec3::new(1.0, 0.4, 0.4)
|
[1.0, 0.4, 0.4]
|
||||||
} else {
|
} else {
|
||||||
Vec3::new(0.4, 1.0, 0.4)
|
[0.4, 1.0, 0.4]
|
||||||
};
|
};
|
||||||
let world: Box<Hit> = if opt.use_accel {
|
let world: Box<Hit> = if opt.use_accel {
|
||||||
Box::new(KDTree::new(random_scene(ground_color), time_min, time_max))
|
Box::new(KDTree::new(random_scene(ground_color), time_min, time_max))
|
||||||
@ -54,22 +54,25 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_scene(ground_color: Vec3) -> Vec<Box<Hit>> {
|
fn random_scene<V>(ground_color: V) -> Vec<Box<Hit>>
|
||||||
|
where
|
||||||
|
V: Into<Vec3>,
|
||||||
|
{
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let checker = true;
|
let checker = true;
|
||||||
let ground_texture: Box<Texture> = if checker {
|
let ground_material: Box<Material> = if checker {
|
||||||
Box::new(CheckerTexture::new(
|
Box::new(Lambertian::new(CheckerTexture::new(
|
||||||
Box::new(ConstantTexture::new(Vec3::new(0., 0., 0.))),
|
ConstantTexture::new([0., 0., 0.]),
|
||||||
Box::new(ConstantTexture::new(ground_color)),
|
ConstantTexture::new(ground_color),
|
||||||
))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Box::new(ConstantTexture::new(ground_color))
|
Box::new(Lambertian::new(ConstantTexture::new(ground_color)))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut objects: Vec<Box<Hit>> = vec![Box::new(Sphere::new(
|
let mut objects: Vec<Box<Hit>> = vec![Box::new(Sphere::new(
|
||||||
Vec3::new(0., -1000., 0.),
|
[0., -1000., 0.],
|
||||||
1000.,
|
1000.,
|
||||||
Box::new(Lambertian::new(ground_texture)),
|
ground_material,
|
||||||
))];
|
))];
|
||||||
let mut random = || rng.gen_range::<f32>(0., 1.);
|
let mut random = || rng.gen_range::<f32>(0., 1.);
|
||||||
|
|
||||||
@ -78,34 +81,34 @@ fn random_scene(ground_color: Vec3) -> Vec<Box<Hit>> {
|
|||||||
let choose_mat = random();
|
let choose_mat = random();
|
||||||
let center = Vec3::new(a as f32 + 0.9 * random(), 0.2, b as f32 + 0.9 * random());
|
let center = Vec3::new(a as f32 + 0.9 * random(), 0.2, b as f32 + 0.9 * random());
|
||||||
if (center - Vec3::new(4., 0.2, 0.)).length() > 0.9 {
|
if (center - Vec3::new(4., 0.2, 0.)).length() > 0.9 {
|
||||||
let sphere = if choose_mat < 0.8 {
|
let sphere: Box<Hit> = if choose_mat < 0.8 {
|
||||||
// diffuse
|
// diffuse
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
center,
|
center,
|
||||||
0.2,
|
0.2,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new([
|
||||||
random() * random(),
|
random() * random(),
|
||||||
random() * random(),
|
random() * random(),
|
||||||
random() * random(),
|
random() * random(),
|
||||||
))))),
|
])),
|
||||||
))
|
))
|
||||||
} else if choose_mat < 0.95 {
|
} else if choose_mat < 0.95 {
|
||||||
// metal
|
// metal
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
center,
|
center,
|
||||||
0.2,
|
0.2,
|
||||||
Box::new(Metal::new(
|
Metal::new(
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
0.5 * (1. + random()),
|
0.5 * (1. + random()),
|
||||||
0.5 * (1. + random()),
|
0.5 * (1. + random()),
|
||||||
0.5 * (1. + random()),
|
0.5 * (1. + random()),
|
||||||
),
|
),
|
||||||
0.5 * random(),
|
0.5 * random(),
|
||||||
)),
|
),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
// glass
|
// glass
|
||||||
Box::new(Sphere::new(center, 0.2, Box::new(Dielectric::new(1.5))))
|
Box::new(Sphere::new(center, 0.2, Dielectric::new(1.5)))
|
||||||
};
|
};
|
||||||
objects.push(sphere);
|
objects.push(sphere);
|
||||||
};
|
};
|
||||||
@ -116,19 +119,17 @@ fn random_scene(ground_color: Vec3) -> Vec<Box<Hit>> {
|
|||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 1., 0.),
|
Vec3::new(0., 1., 0.),
|
||||||
1.0,
|
1.0,
|
||||||
Box::new(Dielectric::new(1.5)),
|
Dielectric::new(1.5),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(-4., 1., 0.),
|
Vec3::new(-4., 1., 0.),
|
||||||
1.0,
|
1.0,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.4, 0.2, 0.1))),
|
||||||
0.4, 0.2, 0.1,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(4., 1., 0.),
|
Vec3::new(4., 1., 0.),
|
||||||
1.0,
|
1.0,
|
||||||
Box::new(Metal::new(Vec3::new(0.7, 0.6, 0.5), 0.0)),
|
Metal::new(Vec3::new(0.7, 0.6, 0.5), 0.0),
|
||||||
)),
|
)),
|
||||||
];
|
];
|
||||||
objects.extend(more);
|
objects.extend(more);
|
||||||
|
|||||||
@ -33,21 +33,17 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., -1.),
|
Vec3::new(0., 0., -1.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
0.1, 0.2, 0.5,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., -100.5, -1.),
|
Vec3::new(0., -100.5, -1.),
|
||||||
100.,
|
100.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.8, 0.8, 0.8))),
|
||||||
0.8, 0.8, 0.8,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., -1.),
|
Vec3::new(1., 0., -1.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2),
|
||||||
)),
|
)),
|
||||||
Box::new(MovingSphere::new(
|
Box::new(MovingSphere::new(
|
||||||
Vec3::new(-1., 0., -1.25),
|
Vec3::new(-1., 0., -1.25),
|
||||||
@ -55,9 +51,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.5,
|
0.5,
|
||||||
time_min,
|
time_min,
|
||||||
time_max,
|
time_max,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.8, 0.2))),
|
||||||
0.2, 0.8, 0.2,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
time_min,
|
time_min,
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
use cuboid::Cuboid;
|
use cuboid::Cuboid;
|
||||||
use flip_normals::FlipNormals;
|
use flip_normals::FlipNormals;
|
||||||
@ -38,43 +40,41 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
let objects: Vec<Box<Hit>> = vec![
|
let objects: Vec<Box<Hit>> = vec![
|
||||||
// Box1
|
// Box1
|
||||||
Box::new(Translate::new(
|
Box::new(Translate::new(
|
||||||
Box::new(RotateY::new(
|
RotateY::new(
|
||||||
Box::new(Cuboid::new(
|
Cuboid::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
Vec3::new(165., 165., 165.),
|
Vec3::new(165., 165., 165.),
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Arc::new(Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||||
0.73, 0.73, 0.73,
|
0.73, 0.73, 0.73,
|
||||||
))))),
|
)))),
|
||||||
)),
|
),
|
||||||
-18.,
|
-18.,
|
||||||
)),
|
),
|
||||||
Vec3::new(100., 0., 0.),
|
Vec3::new(100., 0., 0.),
|
||||||
)),
|
)),
|
||||||
// Box2
|
// Box2
|
||||||
Box::new(Translate::new(
|
Box::new(Translate::new(
|
||||||
Box::new(RotateY::new(
|
RotateY::new(
|
||||||
Box::new(Cuboid::new(
|
Cuboid::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
Vec3::new(165., 330., 165.),
|
Vec3::new(165., 330., 165.),
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Arc::new(Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||||
0.73, 0.73, 0.73,
|
0.73, 0.73, 0.73,
|
||||||
))))),
|
)))),
|
||||||
)),
|
),
|
||||||
15.,
|
15.,
|
||||||
)),
|
),
|
||||||
Vec3::new(265., 0., 295.),
|
Vec3::new(265., 0., 295.),
|
||||||
)),
|
)),
|
||||||
// Green wall left
|
// Green wall left
|
||||||
Box::new(FlipNormals::new(Box::new(YZRect::new(
|
Box::new(FlipNormals::new(YZRect::new(
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
555.,
|
555.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.12, 0.45, 0.15))),
|
||||||
0.12, 0.45, 0.15,
|
))),
|
||||||
))))),
|
|
||||||
)))),
|
|
||||||
// Red floor right
|
// Red floor right
|
||||||
Box::new(YZRect::new(
|
Box::new(YZRect::new(
|
||||||
0.,
|
0.,
|
||||||
@ -82,9 +82,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
0.,
|
0.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.65, 0.05, 0.05))),
|
||||||
0.65, 0.05, 0.05,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
// Light in ceiling
|
// Light in ceiling
|
||||||
Box::new(XZRect::new(
|
Box::new(XZRect::new(
|
||||||
@ -93,21 +91,17 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
227.,
|
227.,
|
||||||
332.,
|
332.,
|
||||||
554.,
|
554.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(15., 15., 15.))),
|
||||||
Vec3::new(15., 15., 15.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
// Grey ceiling
|
// Grey ceiling
|
||||||
Box::new(FlipNormals::new(Box::new(XZRect::new(
|
Box::new(FlipNormals::new(XZRect::new(
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
555.,
|
555.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.73, 0.73, 0.73))),
|
||||||
0.73, 0.73, 0.73,
|
))),
|
||||||
))))),
|
|
||||||
)))),
|
|
||||||
// Grey floor
|
// Grey floor
|
||||||
Box::new(XZRect::new(
|
Box::new(XZRect::new(
|
||||||
0.,
|
0.,
|
||||||
@ -115,21 +109,17 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
0.,
|
0.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.73, 0.73, 0.73))),
|
||||||
0.73, 0.73, 0.73,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
// Grey back wall
|
// Grey back wall
|
||||||
Box::new(FlipNormals::new(Box::new(XYRect::new(
|
Box::new(FlipNormals::new(XYRect::new(
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
0.,
|
0.,
|
||||||
555.,
|
555.,
|
||||||
555.,
|
555.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.73, 0.73, 0.73))),
|
||||||
0.73, 0.73, 0.73,
|
))),
|
||||||
))))),
|
|
||||||
)))),
|
|
||||||
];
|
];
|
||||||
let world: Box<Hit> = if opt.use_accel {
|
let world: Box<Hit> = if opt.use_accel {
|
||||||
Box::new(KDTree::new(objects, time_min, time_max))
|
Box::new(KDTree::new(objects, time_min, time_max))
|
||||||
|
|||||||
@ -45,17 +45,13 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
||||||
let objects: Vec<Box<Hit>> = vec![
|
let objects: Vec<Box<Hit>> = vec![
|
||||||
// Big sphere
|
// Big sphere
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(Vec3::new(0., 2., 0.), 2.0, Lambertian::new(it))),
|
||||||
Vec3::new(0., 2., 0.),
|
|
||||||
2.0,
|
|
||||||
Box::new(Lambertian::new(Box::new(it))),
|
|
||||||
)),
|
|
||||||
// Earth sized sphere
|
// Earth sized sphere
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., -1000., 0.),
|
Vec3::new(0., -1000., 0.),
|
||||||
1000.,
|
1000.,
|
||||||
// Box::new(Lambertian::new(ground_color)),
|
// Box::new(Lambertian::new(ground_color)),
|
||||||
Box::new(Lambertian::new(Box::new(NoiseTexture::with_scale(10.)))),
|
Lambertian::new(NoiseTexture::with_scale(10.)),
|
||||||
)),
|
)),
|
||||||
Box::new(XZRect::new(
|
Box::new(XZRect::new(
|
||||||
-100.,
|
-100.,
|
||||||
@ -63,9 +59,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
-100.,
|
-100.,
|
||||||
1000.,
|
1000.,
|
||||||
60.,
|
60.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 1.))),
|
||||||
Vec3::new(1., 1., 1.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(YZRect::new(
|
Box::new(YZRect::new(
|
||||||
1.,
|
1.,
|
||||||
@ -73,9 +67,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
-1.,
|
-1.,
|
||||||
1.,
|
1.,
|
||||||
4.,
|
4.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 0., 4.))),
|
||||||
Vec3::new(4., 0., 4.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(YZRect::new(
|
Box::new(YZRect::new(
|
||||||
1.,
|
1.,
|
||||||
@ -83,9 +75,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
-1.,
|
-1.,
|
||||||
1.,
|
1.,
|
||||||
-4.,
|
-4.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 4., 0.))),
|
||||||
Vec3::new(0., 4., 0.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(XZRect::new(
|
Box::new(XZRect::new(
|
||||||
-1.,
|
-1.,
|
||||||
@ -93,9 +83,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
-1.,
|
-1.,
|
||||||
1.,
|
1.,
|
||||||
6.,
|
6.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 4., 0.))),
|
||||||
Vec3::new(4., 4., 0.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(XYRect::new(
|
Box::new(XYRect::new(
|
||||||
-1.,
|
-1.,
|
||||||
@ -103,9 +91,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
1.,
|
1.,
|
||||||
3.,
|
3.,
|
||||||
-4.,
|
-4.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 0., 4.))),
|
||||||
Vec3::new(0., 0., 4.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(XYRect::new(
|
Box::new(XYRect::new(
|
||||||
-1.,
|
-1.,
|
||||||
@ -113,23 +99,21 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
1.,
|
1.,
|
||||||
3.,
|
3.,
|
||||||
4.,
|
4.,
|
||||||
Box::new(DiffuseLight::new(Box::new(ConstantTexture::new(
|
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 4., 4.))),
|
||||||
Vec3::new(0., 4., 4.),
|
|
||||||
)))),
|
|
||||||
)),
|
)),
|
||||||
/*
|
/*
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Box::new(Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||||
0.1, 0.2, 0.5,
|
0.1, 0.2, 0.5,
|
||||||
))))),
|
)))),
|
||||||
)),
|
)),
|
||||||
// Shiny sphere
|
// Shiny sphere
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., 0.),
|
Vec3::new(1., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2)),
|
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||||
)),
|
)),
|
||||||
Box::new(MovingSphere::new(
|
Box::new(MovingSphere::new(
|
||||||
Vec3::new(-1., 0., -0.25),
|
Vec3::new(-1., 0., -0.25),
|
||||||
@ -137,9 +121,9 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.5,
|
0.5,
|
||||||
0.,
|
0.,
|
||||||
1.,
|
1.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||||
0.2, 0.8, 0.2,
|
0.2, 0.8, 0.2,
|
||||||
))))),
|
))),
|
||||||
)),
|
)),
|
||||||
*/
|
*/
|
||||||
];
|
];
|
||||||
|
|||||||
@ -30,9 +30,9 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
time_max,
|
time_max,
|
||||||
);
|
);
|
||||||
let ground_color = if opt.use_accel {
|
let ground_color = if opt.use_accel {
|
||||||
Box::new(ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4)))
|
ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4))
|
||||||
} else {
|
} else {
|
||||||
Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4)))
|
ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))
|
||||||
};
|
};
|
||||||
|
|
||||||
let objects: Vec<Box<Hit>> = vec![
|
let objects: Vec<Box<Hit>> = vec![
|
||||||
@ -40,19 +40,17 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., -1.),
|
Vec3::new(0., 0., -1.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
0.1, 0.2, 0.5,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., -100.5, -1.),
|
Vec3::new(0., -100.5, -1.),
|
||||||
100.,
|
100.,
|
||||||
Box::new(Lambertian::new(ground_color)),
|
Lambertian::new(ground_color),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., -1.),
|
Vec3::new(1., 0., -1.),
|
||||||
0.5,
|
0.5,
|
||||||
Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)),
|
Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2),
|
||||||
)),
|
)),
|
||||||
Box::new(MovingSphere::new(
|
Box::new(MovingSphere::new(
|
||||||
Vec3::new(-1., 0., -1.25),
|
Vec3::new(-1., 0., -1.25),
|
||||||
@ -60,9 +58,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.5,
|
0.5,
|
||||||
0.,
|
0.,
|
||||||
1.,
|
1.,
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.8, 0.2))),
|
||||||
0.2, 0.8, 0.2,
|
|
||||||
))))),
|
|
||||||
)),
|
)),
|
||||||
];
|
];
|
||||||
let world: Box<Hit> = if opt.use_accel {
|
let world: Box<Hit> = if opt.use_accel {
|
||||||
|
|||||||
@ -8,10 +8,13 @@ use ray::Ray;
|
|||||||
use vec3::dot;
|
use vec3::dot;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub struct Sphere {
|
pub struct Sphere<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
center: Vec3,
|
center: Vec3,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
material: Box<Material>,
|
material: M,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sphere_uv(p: Vec3) -> (f32, f32) {
|
pub fn get_sphere_uv(p: Vec3) -> (f32, f32) {
|
||||||
@ -22,17 +25,26 @@ pub fn get_sphere_uv(p: Vec3) -> (f32, f32) {
|
|||||||
(u, v)
|
(u, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl<M> Sphere<M>
|
||||||
pub fn new(center: Vec3, radius: f32, material: Box<Material>) -> Sphere {
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
|
pub fn new<V>(center: V, radius: f32, material: M) -> Sphere<M>
|
||||||
|
where
|
||||||
|
V: Into<Vec3>,
|
||||||
|
{
|
||||||
Sphere {
|
Sphere {
|
||||||
center,
|
center: center.into(),
|
||||||
radius,
|
radius,
|
||||||
material,
|
material,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for Sphere {
|
impl<M> Hit for Sphere<M>
|
||||||
|
where
|
||||||
|
M: Material,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let oc = r.origin - self.center;
|
let oc = r.origin - self.center;
|
||||||
let a = dot(r.direction, r.direction);
|
let a = dot(r.direction, r.direction);
|
||||||
@ -49,7 +61,7 @@ impl Hit for Sphere {
|
|||||||
uv,
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center) / self.radius,
|
normal: (point - self.center) / self.radius,
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
||||||
@ -61,7 +73,7 @@ impl Hit for Sphere {
|
|||||||
uv,
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center) / self.radius,
|
normal: (point - self.center) / self.radius,
|
||||||
material: &*self.material,
|
material: &self.material,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,13 +7,19 @@ pub trait Texture: Send + Sync {
|
|||||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3;
|
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ConstantTexture {
|
pub struct ConstantTexture {
|
||||||
color: Vec3,
|
color: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstantTexture {
|
impl ConstantTexture {
|
||||||
pub fn new(color: Vec3) -> ConstantTexture {
|
pub fn new<V>(color: V) -> ConstantTexture
|
||||||
ConstantTexture { color }
|
where
|
||||||
|
V: Into<Vec3>,
|
||||||
|
{
|
||||||
|
ConstantTexture {
|
||||||
|
color: color.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,18 +29,27 @@ impl Texture for ConstantTexture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CheckerTexture {
|
pub struct CheckerTexture<T>
|
||||||
odd: Box<Texture>,
|
where
|
||||||
even: Box<Texture>,
|
T: Texture,
|
||||||
|
{
|
||||||
|
odd: T,
|
||||||
|
even: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckerTexture {
|
impl<T> CheckerTexture<T>
|
||||||
pub fn new(odd: Box<Texture>, even: Box<Texture>) -> CheckerTexture {
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
|
pub fn new(odd: T, even: T) -> CheckerTexture<T> {
|
||||||
CheckerTexture { odd, even }
|
CheckerTexture { odd, even }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Texture for CheckerTexture {
|
impl<T> Texture for CheckerTexture<T>
|
||||||
|
where
|
||||||
|
T: Texture,
|
||||||
|
{
|
||||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||||
let sines = (10. * p.x).sin() * (10. * p.y).sin() * (10. * p.z).sin();
|
let sines = (10. * p.x).sin() * (10. * p.y).sin() * (10. * p.z).sin();
|
||||||
if sines < 0. {
|
if sines < 0. {
|
||||||
@ -106,3 +121,16 @@ impl Texture for ImageTexture {
|
|||||||
rgb
|
rgb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn constant_texture_from_array() {
|
||||||
|
assert_eq!(
|
||||||
|
ConstantTexture::new(Vec3::new(1., 2., 3.)),
|
||||||
|
ConstantTexture::new([1., 2., 3.])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -4,18 +4,27 @@ use hitable::HitRecord;
|
|||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub struct Translate {
|
pub struct Translate<H>
|
||||||
hitable: Box<Hit>,
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
hitable: H,
|
||||||
offset: Vec3,
|
offset: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Translate {
|
impl<H> Translate<H>
|
||||||
pub fn new(hitable: Box<Hit>, offset: Vec3) -> Translate {
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
|
pub fn new(hitable: H, offset: Vec3) -> Translate<H> {
|
||||||
Translate { hitable, offset }
|
Translate { hitable, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hit for Translate {
|
impl<H> Hit for Translate<H>
|
||||||
|
where
|
||||||
|
H: Hit,
|
||||||
|
{
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let moved_r = Ray::new(r.origin - self.offset, r.direction, r.time);
|
let moved_r = Ray::new(r.origin - self.offset, r.direction, r.time);
|
||||||
if let Some(rec) = self.hitable.hit(moved_r, t_min, t_max) {
|
if let Some(rec) = self.hitable.hit(moved_r, t_min, t_max) {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use std::convert::From;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::ParseFloatError;
|
use std::num::ParseFloatError;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
@ -49,6 +50,16 @@ impl Vec3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<[f32; 3]> for Vec3 {
|
||||||
|
fn from(v: [f32; 3]) -> Self {
|
||||||
|
Vec3 {
|
||||||
|
x: v[0],
|
||||||
|
y: v[1],
|
||||||
|
z: v[2],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Vec3 {
|
impl fmt::Display for Vec3 {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{} {} {}", self.x, self.y, self.z)
|
write!(f, "{} {} {}", self.x, self.y, self.z)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user