some objects to trace
This commit is contained in:
parent
64401937b9
commit
f05390291c
60
src/main.rs
60
src/main.rs
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{convert::identity, error::Error, f32::consts::PI, sync::Arc};
|
||||
|
||||
use glam::{Mat4, vec3};
|
||||
use glam::{Mat4, Vec3, vec3};
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
event::WindowEvent,
|
||||
|
|
@ -13,7 +13,7 @@ use winit::{
|
|||
use crate::{
|
||||
camera::OrbitalCamera,
|
||||
render::lines::{LookParams, Mesh, Pipeline, Vertex},
|
||||
trace::Source,
|
||||
trace::{Scene, Source, Sphere},
|
||||
};
|
||||
|
||||
mod camera;
|
||||
|
|
@ -155,20 +155,54 @@ impl MainWindow {
|
|||
self.pipeline
|
||||
.render(&mut pass, [&Mesh::new(&self.device, &contour)]);
|
||||
|
||||
const BASE_R: f32 = 2.;
|
||||
const BASE_POS: Vec3 = vec3(0., 0., -BASE_R);
|
||||
const BASE: Sphere = Sphere {
|
||||
position: vec3(0., 0., -BASE_R),
|
||||
radius: BASE_R,
|
||||
};
|
||||
fn sphere(pos: Vec3) -> Sphere {
|
||||
Sphere {
|
||||
position: pos,
|
||||
radius: BASE_POS.distance(pos) - BASE_R,
|
||||
}
|
||||
}
|
||||
let scene = Scene {
|
||||
objects: vec![
|
||||
BASE,
|
||||
sphere(vec3(0., 0., 0.1)),
|
||||
sphere(vec3(0.3, 0., 0.1)),
|
||||
sphere(vec3(0.1, 0.3, 0.1)),
|
||||
],
|
||||
};
|
||||
|
||||
let mut prng = rand_pcg::Pcg64::new(42, 0);
|
||||
let rays: Vec<Vertex> = (0..1000)
|
||||
let rays: Vec<Vertex> = (0..10000)
|
||||
.flat_map(|_| {
|
||||
let ray = source.make_ray(&mut prng);
|
||||
[
|
||||
Vertex {
|
||||
pos: ray.base,
|
||||
color: vec3(0., 0., 0.),
|
||||
},
|
||||
Vertex {
|
||||
pos: ray.base + 0.1 * ray.dir,
|
||||
color: vec3(1., 1., 1.),
|
||||
},
|
||||
]
|
||||
if let Some(ray) = scene.trace_ray(ray) {
|
||||
[
|
||||
Vertex {
|
||||
pos: ray.base - 0.02 * ray.dir,
|
||||
color: vec3(1., 1., 1.),
|
||||
},
|
||||
Vertex {
|
||||
pos: ray.base,
|
||||
color: vec3(0., 1., 0.),
|
||||
},
|
||||
]
|
||||
} else {
|
||||
[
|
||||
Vertex {
|
||||
pos: ray.base,
|
||||
color: vec3(1., 1., 1.),
|
||||
},
|
||||
Vertex {
|
||||
pos: ray.base + 0.1 * ray.dir,
|
||||
color: vec3(1., 0., 0.),
|
||||
},
|
||||
]
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
self.pipeline
|
||||
|
|
|
|||
21
src/ray.rs
21
src/ray.rs
|
|
@ -1,6 +1,27 @@
|
|||
use glam::Vec3;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Ray {
|
||||
pub base: Vec3,
|
||||
pub dir: Vec3,
|
||||
}
|
||||
|
||||
impl Ray {
|
||||
pub fn new(base: Vec3, dir: Vec3) -> Self {
|
||||
Ray { base, dir }
|
||||
}
|
||||
|
||||
pub fn normalize(self) -> Self {
|
||||
Self {
|
||||
base: self.base,
|
||||
dir: self.dir.normalize(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn advance(self, amount: f32) -> Self {
|
||||
Self {
|
||||
base: self.base + amount * self.dir,
|
||||
dir: self.dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
42
src/trace.rs
42
src/trace.rs
|
|
@ -71,3 +71,45 @@ impl Source {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sphere {
|
||||
pub position: Vec3,
|
||||
pub radius: f32,
|
||||
}
|
||||
|
||||
impl Sphere {
|
||||
fn trace_ray(&self, ray: Ray) -> Option<f32> {
|
||||
// let t: f32;
|
||||
// let hit = ray.base + t * ray.dir;
|
||||
// (hit - self.position).length() == self.radius;
|
||||
let Ray { base, dir } = ray;
|
||||
let rel = base - self.position;
|
||||
// (rel + t⋅dir)² == r²
|
||||
// rel² − r² + 2⋅t⋅rel⋅dir + t²⋅dir² = 0
|
||||
let a = dir.length_squared();
|
||||
let b2 = rel.dot(dir);
|
||||
let c = rel.length_squared() - self.radius.powi(2);
|
||||
let d4 = b2.powi(2) - a * c;
|
||||
if d4 < 0. {
|
||||
return None;
|
||||
}
|
||||
Some((-b2 - d4.sqrt()) / a)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Scene {
|
||||
pub objects: Vec<Sphere>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn trace_ray(&self, ray: Ray) -> Option<Ray> {
|
||||
let dist = self
|
||||
.objects
|
||||
.iter()
|
||||
.filter_map(|obj| obj.trace_ray(ray))
|
||||
.min_by(f32::total_cmp);
|
||||
Some(ray.advance(dist?))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user