summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-02 01:32:01 +0700
committerRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-02 01:32:01 +0700
commitda70c57d01cf6ffe7c1aab30921eb22cd5197dae (patch)
treecff1c2e09f92445efbfff5dccb7c10522f5b6c33
parent1207c2c55c772155d02a148d76616881f3f6c125 (diff)
upd: diffuse material
-rw-r--r--src/calculus.rs37
-rw-r--r--src/camera.rs25
-rw-r--r--src/global.rs2
3 files changed, 53 insertions, 11 deletions
diff --git a/src/calculus.rs b/src/calculus.rs
index a39c8a5..8865154 100644
--- a/src/calculus.rs
+++ b/src/calculus.rs
@@ -16,6 +16,43 @@ pub mod calculus {
Self { x, y, z }
}
+ fn random() -> Self {
+ let mut rng = rand::rng();
+ Self::new(
+ rng.random(),
+ rng.random(),
+ rng.random(),
+ )
+ }
+
+ fn random_range(min: f32, max: f32) -> Self {
+ let mut rng = rand::rng();
+ Self::new(
+ rng.random_range(min..max),
+ rng.random_range(min..max),
+ rng.random_range(min..max),
+ )
+ }
+
+ fn random_unit() -> Vec3 {
+ loop {
+ let p = Self::random_range(-1.0, 1.0);
+ let lensq = p.mag_sqr();
+ if f32::EPSILON < lensq && lensq <= 1.0 {
+ return p.scalar_mul(1.0 / lensq.sqrt())
+ }
+ }
+ }
+
+ pub fn random_on_hemisphere(normal: &Vec3) -> Vec3 {
+ let on_unit_sphere = Self::random_unit();
+ if on_unit_sphere.dot_prod(normal) > 0.0 {
+ on_unit_sphere
+ } else {
+ on_unit_sphere.scalar_mul(-1.0)
+ }
+ }
+
pub fn add(&self, other: &Self) -> Self {
Self {
x: self.x + other.x,
diff --git a/src/camera.rs b/src/camera.rs
index 8e9cf68..ec37c70 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -13,6 +13,7 @@ pub struct Camera {
delta_pixel_u: Vec3,
delta_pixel_v: Vec3,
pixel_samples_scale: f32,
+ max_depth: usize,
}
impl Camera {
@@ -45,6 +46,8 @@ impl Camera {
&delta_pixel_u.add(&delta_pixel_u).scalar_mul(0.5)
);
+ let max_depth = 50;
+
Self {
aspect_ratio,
image_width,
@@ -55,6 +58,7 @@ impl Camera {
delta_pixel_v,
samples_per_pixel,
pixel_samples_scale,
+ max_depth
}
}
@@ -73,18 +77,18 @@ impl Camera {
}
}
- fn ray_color(&self, ray: &Ray, world: &HittableList) -> Color {
+ fn ray_color(&self, ray: &Ray, world: &HittableList, depth: usize) -> Color {
+ if depth <= 0 {
+ return Color::new(0.0, 0.0, 0.0);
+ }
+
let mut rec = HitRecord::default();
let ray_t = Interval::new(0.0, f32::INFINITY);
if world.hit(ray, ray_t, &mut rec) {
- let color = Color::new(1.0, 1.0, 1.0)
- .add(&Color::new(
- rec.normal.x,
- rec.normal.y,
- rec.normal.z)
- )
- .mul_scalar(0.5);
- return color;
+ let direction = Vec3::random_on_hemisphere(&rec.normal);
+ let origin = rec.position.clone();
+ let r = Ray { origin, direction };
+ return self.ray_color(&r, world, depth - 1).mul_scalar(0.5);
}
let unit_direction = ray.direction.unit();
@@ -97,10 +101,11 @@ impl Camera {
pub fn render(&self, display_buffer: &mut DisplayBuffer, world: &HittableList) {
(0..self.image_height).for_each(|j| {
(0..self.image_width).for_each(|i| {
+ println!("Processing line {} col {}", j, i);
let mut pixel_color = Color::new(0.0, 0.0, 0.0);
(0..self.samples_per_pixel).for_each(|_| {
let r = self.get_ray(i, j);
- let ray_color = self.ray_color(&r, world);
+ let ray_color = self.ray_color(&r, world, self.max_depth);
pixel_color = pixel_color.add(&ray_color);
});
pixel_color = pixel_color.mul_scalar(self.pixel_samples_scale);
diff --git a/src/global.rs b/src/global.rs
index 3f74ba1..3975609 100644
--- a/src/global.rs
+++ b/src/global.rs
@@ -3,7 +3,7 @@ use crate::interval::Interval;
// "Ideal" aspect ratio, allowing fraction
pub const ASPECT_RATIO: f32 = 16.0f32 / 9.0f32;
-pub const IMG_WIDTH: usize = 1000;
+pub const IMG_WIDTH: usize = 400;
pub const IMG_HEIGHT: usize = get_image_height(IMG_WIDTH, ASPECT_RATIO);
pub const VIEWPORT_HEIGHT: f32 = 2.0;