Skip to content

Commit 5e23447

Browse files
committed
fog?
1 parent 7a72210 commit 5e23447

File tree

1 file changed

+94
-24
lines changed

1 file changed

+94
-24
lines changed

src/main.rs

Lines changed: 94 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ fn main() {
137137
println!("let seed = {:?};", seed);
138138
let mut rng : Rng = rand::SeedableRng::from_seed(seed);
139139

140-
let nx = 400;
141-
let ny = 400;
142-
let ns = 10000;
140+
let nx = 200;
141+
let ny = 200;
142+
let ns = 1000;
143143

144144
// let world : Vec<Box<Hitable>> = vec![
145145
// box Sphere{ center: vec3(0.0, 0.0, -1.0), radius: 0.5,
@@ -237,7 +237,7 @@ fn color(rng : &mut Rng, r0 : Ray, world : &Hitable) -> Vec3 {
237237
let mut attenuation = vec3(1.0, 1.0, 1.0);
238238
let mut r = r0;
239239
for ttl in 0..50 {
240-
match world.hit(&r, (0.001, f32::INFINITY)) {
240+
match world.hit(rng, &r, (0.001, f32::INFINITY)) {
241241
Some(hit) => {
242242
let emitted = hit.material.emitted(hit.uv, &hit.p);
243243
accumulator += emitted * attenuation;
@@ -274,7 +274,7 @@ struct HitRecord<'a> {
274274
}
275275

276276
trait Hitable {
277-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord>;
277+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord>;
278278
fn bounding_box(&self, time : (f32, f32)) -> AABB;
279279
}
280280

@@ -311,7 +311,7 @@ fn stationary_sphere(radius : f32, center : Vec3, material : Rc<Material>) -> Sp
311311
}
312312

313313
impl Hitable for Sphere {
314-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
314+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
315315
let center = self.center(r.time);
316316
let oc = &r.origin - &center;
317317
let a = dot(r.direction, r.direction);
@@ -549,10 +549,10 @@ struct BVHNode {
549549
}
550550

551551
impl Hitable for BVHNode {
552-
fn hit<'a>(&'a self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
552+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
553553
if self.bbox.hit(r, dist) {
554-
let l_hit = self.left.hit(r, dist);
555-
let r_hit = self.right.hit(r, dist);
554+
let l_hit = self.left.hit(rng, r, dist);
555+
let r_hit = self.right.hit(rng, r, dist);
556556
return match (l_hit, r_hit) {
557557
(None, h) => h,
558558
(h, None) => h,
@@ -821,7 +821,7 @@ macro_rules! aarect {
821821
}
822822

823823
impl Hitable for $XYRect {
824-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
824+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
825825
let t = (self.$z - r.origin[$Z]) / r.direction[$Z];
826826
if !(dist.0 < t && t < dist.1) {
827827
return None;
@@ -912,31 +912,42 @@ fn cornell_box(rng : &mut Rng) -> Box<Hitable> {
912912
let red : Rc<Material> = Rc::new(Lambertian(ConstantTex(vec3(0.65, 0.05, 0.05))));
913913
let white : Rc<Material> = Rc::new(Lambertian(ConstantTex(0.73 * ONE3)));
914914
let green : Rc<Material> = Rc::new(Lambertian(ConstantTex(vec3(0.12, 0.45, 0.15))));
915-
let light : Rc<Material> = Rc::new(DiffuseLight(ConstantTex(15.0 * ONE3)));
915+
let light : Rc<Material> = Rc::new(DiffuseLight(ConstantTex(7.0 * ONE3)));
916916

917917
list.push(YZRect::new((0.0, 555.0), (0.0, 555.0), 555.0, &green, true));
918918
list.push(YZRect::new((0.0, 555.0), (0.0, 555.0), 0.0, &red, false));
919-
list.push(XZRect::new((213.0, 343.0), (227.0, 332.0), 554.0, &light, false));
919+
list.push(XZRect::new((113.0, 443.0), (127.0, 432.0), 554.0, &light, false));
920920
list.push(XZRect::new((0.0, 555.0), (0.0, 555.0), 555.0, &white, true));
921921
list.push(XZRect::new((0.0, 555.0), (0.0, 555.0), 0.0, &white, false));
922922
list.push(XYRect::new((0.0, 555.0), (0.0, 555.0), 555.0, &white, true));
923923

924-
list.push(translate(ivec3(130, 0, 65),
925-
rotate(ivec3(0, 1, 0), -18.0,
926-
cube(ivec3(0, 0, 0), ivec3(165, 165, 165), &white))));
927-
list.push(translate(ivec3(265, 0, 295),
928-
rotate(ivec3(0, 1, 0), 15.0,
929-
cube(ivec3(0, 0, 0), ivec3(165, 330, 165), &white))));
924+
let b1 = translate(ivec3(130, 1, 65),
925+
rotate(ivec3(0, 1, 0), -18.0,
926+
cube(ivec3(0, 0, 0), ivec3(165, 165, 165), &white)));
927+
let b2 = translate(ivec3(265, 1, 295),
928+
rotate(ivec3(0, 1, 0), 15.0,
929+
cube(ivec3(0, 0, 0), ivec3(165, 330, 165), &white)));
930+
931+
list.push(box ConstantMedium {
932+
boundary: b1,
933+
density: 0.01,
934+
phase_function: box Isotropic(ConstantTex(ivec3(1, 1, 1))),
935+
});
936+
list.push(box ConstantMedium {
937+
boundary: b2,
938+
density: 0.01,
939+
phase_function: box Isotropic(ConstantTex(ivec3(0, 0, 0))),
940+
});
930941

931942
return into_bvh(rng, list, (0.0, 1.0));
932943
}
933944

934945
struct FlipNormals<H : Hitable>(H);
935946

936947
impl<H : Hitable> Hitable for FlipNormals<H> {
937-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
948+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
938949
let FlipNormals(ref inner) = *self;
939-
inner.hit(r, dist).map(|mut hit| {
950+
inner.hit(rng, r, dist).map(|mut hit| {
940951
hit.normal = -1.0 * hit.normal;
941952
return hit;
942953
})
@@ -972,10 +983,10 @@ fn translate(offset : Vec3, inner : Box<Hitable>) -> Box<Hitable> {
972983
}
973984

974985
impl Hitable for Translate {
975-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
986+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
976987
let mut r = (*r).clone();
977988
r.origin -= self.offset;
978-
self.inner.hit(&r, dist).map(|mut hit| {
989+
self.inner.hit(rng, &r, dist).map(|mut hit| {
979990
hit.p += self.offset;
980991
hit
981992
})
@@ -1022,11 +1033,11 @@ fn rotate(axis : Vec3, angle : f32, inner : Box<Hitable>) -> Box<Hitable> {
10221033
}
10231034

10241035
impl Hitable for Rotate {
1025-
fn hit(&self, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
1036+
fn hit(&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)) -> Option<HitRecord> {
10261037
let mut r = (*r).clone();
10271038
r.origin = self.mat * r.origin;
10281039
r.direction = self.mat * r.direction;
1029-
self.inner.hit(&r, dist).map(|mut hit| {
1040+
self.inner.hit(rng, &r, dist).map(|mut hit| {
10301041
let inv = self.mat.transpose();
10311042
hit.p = inv * hit.p;
10321043
hit.normal = inv * hit.normal;
@@ -1046,3 +1057,62 @@ impl Hitable for Rotate {
10461057
b
10471058
}
10481059
}
1060+
1061+
struct ConstantMedium {
1062+
boundary : Box<Hitable>,
1063+
density : f32,
1064+
phase_function : Box<Material>,
1065+
}
1066+
1067+
impl Hitable for ConstantMedium {
1068+
fn hit(
1069+
&self, rng : &mut Rng, r : &Ray, dist : (f32, f32)
1070+
) -> Option<HitRecord> {
1071+
let mhit1 = self.boundary.hit(rng, r, dist);
1072+
if let Some(mut hit1) = mhit1 {
1073+
let mhit2 = self.boundary.hit(rng, r, (hit1.t + 0.0001, dist.1));
1074+
if let Some(mut hit2) = mhit2 {
1075+
// assert!(hit1.t >= dist.0);
1076+
hit1.t = hit1.t.max(dist.0);
1077+
// assert!(hit2.t <= dist.1);
1078+
hit2.t = hit2.t.min(dist.1);
1079+
// assert!(hit1.t > hit2.t);
1080+
if hit1.t > hit2.t {
1081+
return None
1082+
}
1083+
hit1.t = hit1.t.max(0.0);
1084+
1085+
let dist_inside = (hit2.t - hit1.t) * r.direction.len();
1086+
let hit_dist = -(rng.gen::<f32>().ln()) / self.density;
1087+
if hit_dist < dist_inside {
1088+
let t = hit1.t + hit_dist / r.direction.len();
1089+
let p = r.at(t);
1090+
let normal = ivec3(1, 0, 0);
1091+
return Some(HitRecord {
1092+
t: t, p: p,
1093+
normal: normal, material: &*self.phase_function,
1094+
uv: (0.0, 0.0),
1095+
})
1096+
}
1097+
}
1098+
}
1099+
return None
1100+
}
1101+
1102+
fn bounding_box(&self, time : (f32, f32)) -> AABB {
1103+
self.boundary.bounding_box(time)
1104+
}
1105+
}
1106+
1107+
struct Isotropic<T : Texture>(T);
1108+
1109+
impl<T : Texture> Material for Isotropic<T> {
1110+
fn scatter(
1111+
&self, rng : &mut Rng, r_in : &Ray, hit : &HitRecord
1112+
) -> Option<(Ray, Vec3)> {
1113+
let Isotropic(ref albedo) = *self;
1114+
let mut r = (*r_in).clone();
1115+
r.direction = rand_in_ball(rng).unit();
1116+
Some((r, albedo.tex_lookup(hit.uv, &hit.p)))
1117+
}
1118+
}

0 commit comments

Comments
 (0)