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 image;
|
||||
mod triangle;
|
||||
mod surface;
|
||||
mod bvh;
|
||||
mod halton;
|
||||
|
||||
|
@ -21,9 +22,9 @@ use docopt::Docopt;
|
|||
|
||||
use math::{Point, Matrix4x4};
|
||||
use ray::Ray;
|
||||
use bbox::BBox;
|
||||
use camera::Camera;
|
||||
use renderer::Renderer;
|
||||
use surface::triangle_mesh::TriangleMesh;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
@ -73,7 +74,7 @@ fn main() {
|
|||
println!("Ray size: {} bytes", mem::size_of::<Ray>());
|
||||
|
||||
// Generate a scene of triangles
|
||||
let mut triangles = {
|
||||
let mesh = TriangleMesh::from_triangles({
|
||||
let mut triangles = Vec::new();
|
||||
let xres = 32;
|
||||
let yres = 32;
|
||||
|
@ -97,14 +98,6 @@ fn main() {
|
|||
}
|
||||
}
|
||||
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.");
|
||||
|
||||
|
@ -118,7 +111,7 @@ fn main() {
|
|||
resolution: (512, 512),
|
||||
spp: samples_per_pixel as usize,
|
||||
camera: cam,
|
||||
scene: (triangles, accel),
|
||||
scene: mesh,
|
||||
};
|
||||
|
||||
r.render();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// use renderer::Renderer;
|
||||
//
|
||||
// use super::DataTree;
|
||||
#![allow(dead_code)]
|
||||
|
||||
// pub fn parse_frame<'a>(tree: &DataTree) -> Renderer<'a> {
|
||||
// unimplemented!()
|
||||
// }
|
||||
use renderer::Renderer;
|
||||
|
||||
use super::DataTree;
|
||||
|
||||
pub fn parse_frame(tree: &DataTree) -> Renderer {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use camera::Camera;
|
||||
use halton;
|
||||
use math::{Point, fast_logit};
|
||||
use math::fast_logit;
|
||||
use image::Image;
|
||||
use bvh::BVH;
|
||||
use triangle;
|
||||
use surface;
|
||||
use surface::Surface;
|
||||
|
||||
pub struct Renderer {
|
||||
pub output_file: String,
|
||||
pub resolution: (usize, usize),
|
||||
pub spp: usize,
|
||||
pub camera: Camera,
|
||||
pub scene: (Vec<(Point, Point, Point)>, BVH),
|
||||
pub scene: surface::triangle_mesh::TriangleMesh,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
|
@ -44,39 +46,36 @@ impl Renderer {
|
|||
};
|
||||
ray.id = si as u32;
|
||||
rays.push(ray);
|
||||
isects.push((false, 0.0, 0.0));
|
||||
isects.push(surface::SurfaceIntersection::Miss);
|
||||
}
|
||||
|
||||
// Test rays against scene
|
||||
self.scene.1.traverse(&mut rays, &self.scene.0, |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] = (true, tri_u, tri_v);
|
||||
r.max_t = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
self.scene.intersect_rays(&mut rays, &mut isects);
|
||||
|
||||
// Calculate color based on ray hits
|
||||
let mut r = 0.0;
|
||||
let mut g = 0.0;
|
||||
let mut b = 0.0;
|
||||
for &(hit, u, v) in isects.iter() {
|
||||
if hit {
|
||||
r += u;
|
||||
g += v;
|
||||
b += (1.0 - u - v).max(0.0);
|
||||
for isect in isects.iter() {
|
||||
if let &surface::SurfaceIntersection::Hit{
|
||||
t: _,
|
||||
pos: _,
|
||||
nor: _,
|
||||
space: _,
|
||||
uv,
|
||||
} = isect {
|
||||
r += uv.0;
|
||||
g += uv.1;
|
||||
b += (1.0 - uv.0 - uv.1).max(0.0);
|
||||
} else {
|
||||
r += 0.02;
|
||||
g += 0.02;
|
||||
b += 0.02;
|
||||
}
|
||||
}
|
||||
r = 255.0 * sRGB_gamma(r / self.spp as f32);
|
||||
g = 255.0 * sRGB_gamma(g / self.spp as f32);
|
||||
b = 255.0 * sRGB_gamma(b / self.spp as f32);
|
||||
r = 255.0 * srgb_gamma(r / self.spp as f32);
|
||||
g = 255.0 * srgb_gamma(g / self.spp as f32);
|
||||
b = 255.0 * srgb_gamma(b / self.spp as f32);
|
||||
|
||||
// Set pixel color
|
||||
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 {
|
||||
n * 12.92
|
||||
} 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 {
|
||||
n / 12.92
|
||||
} 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