From 6c56a31726ab47c78557549789117b6d42300b63 Mon Sep 17 00:00:00 2001 From: numzero Date: Tue, 26 Mar 2024 00:42:22 +0300 Subject: [PATCH] Use ray tracing --- src/main.rs | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index b228c1e..e0a40d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,8 +6,7 @@ use std::f32::consts::PI; use std::io::{BufRead, BufReader, BufWriter}; use std::io::Write; use rand::Rng; -use glm; -use glm::{dot, ivec2, IVec2, ivec3, to_ivec3, vec2, Vec2, Vec3}; +use glm::*; use crate::mesh_loader::load_mesh; const W: i32 = 800; @@ -106,13 +105,34 @@ fn main() -> io::Result<()> { 1.0, 0.0, 0.0, 0.0, pitch.cos(), -pitch.sin(), 0.0, pitch.sin(), pitch.cos()); - let m_camera = m_roll * m_pitch * m_yaw; - for f in mesh { - let vs = f.vertices - .map(|v| m_camera * v) - .map(|v| vec2(W as f32 * 0.5 + v.x * SCALE, H as f32 * 0.5 + v.y * SCALE)); - let color = glm::clamp(to_ivec3(f.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); - img.draw_tri(vs[0], vs[1], vs[2], Color(color.x as u8, color.y as u8, color.z as u8)); + let m_view = m_roll * m_pitch * m_yaw; + let m_camera = transpose(&m_view); + let img_size = vec2(W as f32, H as f32); + for y in 0..H { + for x in 0..W { + let img_coords: Vec2 = vec2(x as f32, y as f32); + + // perspective projection + let off = (img_coords - img_size * 0.5) / (img_size.y * 0.5); + let base = vec3(0.0, 0.0, -10.0); + let ray = vec3(off.x, off.y, 1.0); + + // orthographic projection + let off = (img_coords - img_size * 0.5) / SCALE; + let base = vec3(off.x, off.y, -10.0); + let ray = vec3(0.0, 0.0, 1.0); + + let base = m_camera * base; + let ray = m_camera * normalize(ray); + + for f in &mesh { + let color = glm::clamp(to_ivec3(f.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); + let ds = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); + if ds.into_iter().all(|d| d > 0.0) { + img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8)); + } + } + } } let f = File::create("1.ppm")?; let mut f = BufWriter::new(f); @@ -121,3 +141,8 @@ fn main() -> io::Result<()> { f.write(img.data()); Ok(()) } + +fn edge_dist(a: Vec3, b: Vec3, base: Vec3, dir: Vec3) -> f32 { + let edge = normalize(b - a); + dot(edge, cross(base - a, base + dir - a)) +}