Use ray tracing

This commit is contained in:
numzero 2024-03-26 00:42:22 +03:00
parent af5322a47e
commit 6c56a31726

View File

@ -6,8 +6,7 @@ use std::f32::consts::PI;
use std::io::{BufRead, BufReader, BufWriter}; use std::io::{BufRead, BufReader, BufWriter};
use std::io::Write; use std::io::Write;
use rand::Rng; use rand::Rng;
use glm; use glm::*;
use glm::{dot, ivec2, IVec2, ivec3, to_ivec3, vec2, Vec2, Vec3};
use crate::mesh_loader::load_mesh; use crate::mesh_loader::load_mesh;
const W: i32 = 800; const W: i32 = 800;
@ -106,13 +105,34 @@ fn main() -> io::Result<()> {
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, pitch.cos(), -pitch.sin(), 0.0, pitch.cos(), -pitch.sin(),
0.0, pitch.sin(), pitch.cos()); 0.0, pitch.sin(), pitch.cos());
let m_camera = m_roll * m_pitch * m_yaw; let m_view = m_roll * m_pitch * m_yaw;
for f in mesh { let m_camera = transpose(&m_view);
let vs = f.vertices let img_size = vec2(W as f32, H as f32);
.map(|v| m_camera * v) for y in 0..H {
.map(|v| vec2(W as f32 * 0.5 + v.x * SCALE, H as f32 * 0.5 + v.y * SCALE)); for x in 0..W {
let color = glm::clamp(to_ivec3(f.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); let img_coords: Vec2 = vec2(x as f32, y as f32);
img.draw_tri(vs[0], vs[1], vs[2], Color(color.x as u8, color.y as u8, color.z as u8));
// 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 f = File::create("1.ppm")?;
let mut f = BufWriter::new(f); let mut f = BufWriter::new(f);
@ -121,3 +141,8 @@ fn main() -> io::Result<()> {
f.write(img.data()); f.write(img.data());
Ok(()) 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))
}