Started creating an interface for surfaces.
Testing it out by making a bogus TriangleMesh surface type.
This commit is contained in:
parent
d7f6142749
commit
907d15f643
15
src/main.rs
15
src/main.rs
|
@ -12,6 +12,7 @@ mod parse;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod image;
|
mod image;
|
||||||
mod triangle;
|
mod triangle;
|
||||||
|
mod surface;
|
||||||
mod bvh;
|
mod bvh;
|
||||||
mod halton;
|
mod halton;
|
||||||
|
|
||||||
|
@ -21,9 +22,9 @@ use docopt::Docopt;
|
||||||
|
|
||||||
use math::{Point, Matrix4x4};
|
use math::{Point, Matrix4x4};
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use bbox::BBox;
|
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
use renderer::Renderer;
|
use renderer::Renderer;
|
||||||
|
use surface::triangle_mesh::TriangleMesh;
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ fn main() {
|
||||||
println!("Ray size: {} bytes", mem::size_of::<Ray>());
|
println!("Ray size: {} bytes", mem::size_of::<Ray>());
|
||||||
|
|
||||||
// Generate a scene of triangles
|
// Generate a scene of triangles
|
||||||
let mut triangles = {
|
let mesh = TriangleMesh::from_triangles({
|
||||||
let mut triangles = Vec::new();
|
let mut triangles = Vec::new();
|
||||||
let xres = 32;
|
let xres = 32;
|
||||||
let yres = 32;
|
let yres = 32;
|
||||||
|
@ -97,14 +98,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triangles
|
triangles
|
||||||
};
|
|
||||||
let accel = bvh::BVH::from_objects(&mut triangles[..], 3, |tri| {
|
|
||||||
let minimum = tri.0.min(tri.1.min(tri.2));
|
|
||||||
let maximum = tri.0.max(tri.1.max(tri.2));
|
|
||||||
BBox {
|
|
||||||
min: minimum,
|
|
||||||
max: maximum,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
println!("Scene built.");
|
println!("Scene built.");
|
||||||
|
|
||||||
|
@ -118,7 +111,7 @@ fn main() {
|
||||||
resolution: (512, 512),
|
resolution: (512, 512),
|
||||||
spp: samples_per_pixel as usize,
|
spp: samples_per_pixel as usize,
|
||||||
camera: cam,
|
camera: cam,
|
||||||
scene: (triangles, accel),
|
scene: mesh,
|
||||||
};
|
};
|
||||||
|
|
||||||
r.render();
|
r.render();
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
// use renderer::Renderer;
|
#![allow(dead_code)]
|
||||||
//
|
|
||||||
// use super::DataTree;
|
|
||||||
|
|
||||||
// pub fn parse_frame<'a>(tree: &DataTree) -> Renderer<'a> {
|
use renderer::Renderer;
|
||||||
// unimplemented!()
|
|
||||||
// }
|
use super::DataTree;
|
||||||
|
|
||||||
|
pub fn parse_frame(tree: &DataTree) -> Renderer {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
use halton;
|
use halton;
|
||||||
use math::{Point, fast_logit};
|
use math::fast_logit;
|
||||||
use image::Image;
|
use image::Image;
|
||||||
use bvh::BVH;
|
use surface;
|
||||||
use triangle;
|
use surface::Surface;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
pub output_file: String,
|
pub output_file: String,
|
||||||
pub resolution: (usize, usize),
|
pub resolution: (usize, usize),
|
||||||
pub spp: usize,
|
pub spp: usize,
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
pub scene: (Vec<(Point, Point, Point)>, BVH),
|
pub scene: surface::triangle_mesh::TriangleMesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
|
@ -44,39 +46,36 @@ impl Renderer {
|
||||||
};
|
};
|
||||||
ray.id = si as u32;
|
ray.id = si as u32;
|
||||||
rays.push(ray);
|
rays.push(ray);
|
||||||
isects.push((false, 0.0, 0.0));
|
isects.push(surface::SurfaceIntersection::Miss);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test rays against scene
|
// Test rays against scene
|
||||||
self.scene.1.traverse(&mut rays, &self.scene.0, |tri, rs| {
|
self.scene.intersect_rays(&mut rays, &mut isects);
|
||||||
for r in rs {
|
|
||||||
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
|
|
||||||
if t < r.max_t {
|
|
||||||
isects[r.id as usize] = (true, tri_u, tri_v);
|
|
||||||
r.max_t = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Calculate color based on ray hits
|
// Calculate color based on ray hits
|
||||||
let mut r = 0.0;
|
let mut r = 0.0;
|
||||||
let mut g = 0.0;
|
let mut g = 0.0;
|
||||||
let mut b = 0.0;
|
let mut b = 0.0;
|
||||||
for &(hit, u, v) in isects.iter() {
|
for isect in isects.iter() {
|
||||||
if hit {
|
if let &surface::SurfaceIntersection::Hit{
|
||||||
r += u;
|
t: _,
|
||||||
g += v;
|
pos: _,
|
||||||
b += (1.0 - u - v).max(0.0);
|
nor: _,
|
||||||
|
space: _,
|
||||||
|
uv,
|
||||||
|
} = isect {
|
||||||
|
r += uv.0;
|
||||||
|
g += uv.1;
|
||||||
|
b += (1.0 - uv.0 - uv.1).max(0.0);
|
||||||
} else {
|
} else {
|
||||||
r += 0.02;
|
r += 0.02;
|
||||||
g += 0.02;
|
g += 0.02;
|
||||||
b += 0.02;
|
b += 0.02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = 255.0 * sRGB_gamma(r / self.spp as f32);
|
r = 255.0 * srgb_gamma(r / self.spp as f32);
|
||||||
g = 255.0 * sRGB_gamma(g / self.spp as f32);
|
g = 255.0 * srgb_gamma(g / self.spp as f32);
|
||||||
b = 255.0 * sRGB_gamma(b / self.spp as f32);
|
b = 255.0 * srgb_gamma(b / self.spp as f32);
|
||||||
|
|
||||||
// Set pixel color
|
// Set pixel color
|
||||||
img.set(x, y, (r as u8, g as u8, b as u8));
|
img.set(x, y, (r as u8, g as u8, b as u8));
|
||||||
|
@ -102,7 +101,7 @@ fn hash_u32(n: u32, seed: u32) -> u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn sRGB_gamma(n: f32) -> f32 {
|
fn srgb_gamma(n: f32) -> f32 {
|
||||||
if n < 0.0031308 {
|
if n < 0.0031308 {
|
||||||
n * 12.92
|
n * 12.92
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,7 +109,7 @@ fn sRGB_gamma(n: f32) -> f32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sRGB_inv_gamma(n: f32) -> f32 {
|
fn srgb_inv_gamma(n: f32) -> f32 {
|
||||||
if n < 0.04045 {
|
if n < 0.04045 {
|
||||||
n / 12.92
|
n / 12.92
|
||||||
} else {
|
} else {
|
||||||
|
|
23
src/surface/mod.rs
Normal file
23
src/surface/mod.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
pub mod triangle_mesh;
|
||||||
|
|
||||||
|
use ray::Ray;
|
||||||
|
use math::{Point, Normal, Matrix4x4};
|
||||||
|
|
||||||
|
|
||||||
|
pub enum SurfaceIntersection {
|
||||||
|
Miss,
|
||||||
|
Occlude,
|
||||||
|
Hit {
|
||||||
|
t: f32,
|
||||||
|
pos: Point,
|
||||||
|
nor: Normal,
|
||||||
|
space: Matrix4x4,
|
||||||
|
uv: (f32, f32),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Surface {
|
||||||
|
fn intersect_rays(&self, rays: &mut [Ray], isects: &mut [SurfaceIntersection]);
|
||||||
|
}
|
54
src/surface/triangle_mesh.rs
Normal file
54
src/surface/triangle_mesh.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use math::{Point, Normal, Matrix4x4};
|
||||||
|
use ray::Ray;
|
||||||
|
use triangle;
|
||||||
|
use bbox::BBox;
|
||||||
|
use bvh::BVH;
|
||||||
|
|
||||||
|
use super::{Surface, SurfaceIntersection};
|
||||||
|
|
||||||
|
pub struct TriangleMesh {
|
||||||
|
geo: Vec<(Point, Point, Point)>,
|
||||||
|
accel: BVH,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TriangleMesh {
|
||||||
|
pub fn from_triangles(mut triangles: Vec<(Point, Point, Point)>) -> TriangleMesh {
|
||||||
|
let accel = BVH::from_objects(&mut triangles[..], 3, |tri| {
|
||||||
|
let minimum = tri.0.min(tri.1.min(tri.2));
|
||||||
|
let maximum = tri.0.max(tri.1.max(tri.2));
|
||||||
|
BBox {
|
||||||
|
min: minimum,
|
||||||
|
max: maximum,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
TriangleMesh {
|
||||||
|
geo: triangles,
|
||||||
|
accel: accel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Surface for TriangleMesh {
|
||||||
|
fn intersect_rays(&self, rays: &mut [Ray], isects: &mut [SurfaceIntersection]) {
|
||||||
|
self.accel.traverse(&mut rays[..], &self.geo, |tri, rs| {
|
||||||
|
for r in rs {
|
||||||
|
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
|
||||||
|
if t < r.max_t {
|
||||||
|
isects[r.id as usize] = SurfaceIntersection::Hit {
|
||||||
|
t: t,
|
||||||
|
pos: r.orig + (r.dir * t),
|
||||||
|
nor: Normal::new(0.0, 0.0, 0.0), // TODO
|
||||||
|
space: Matrix4x4::new(), // TODO
|
||||||
|
uv: (tri_u, tri_v),
|
||||||
|
};
|
||||||
|
r.max_t = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user