Got basic material parsing and rendering working.
Currently only Lambert is supported.
This commit is contained in:
parent
f4d4152543
commit
516803e78a
|
@ -2,6 +2,7 @@ mod data_tree;
|
||||||
mod psy_assembly;
|
mod psy_assembly;
|
||||||
mod psy_light;
|
mod psy_light;
|
||||||
mod psy_mesh_surface;
|
mod psy_mesh_surface;
|
||||||
|
mod psy_surface_shader;
|
||||||
mod psy;
|
mod psy;
|
||||||
pub mod basics;
|
pub mod basics;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use scene::{Assembly, AssemblyBuilder, Object};
|
||||||
use super::DataTree;
|
use super::DataTree;
|
||||||
use super::psy_light::{parse_sphere_light, parse_rectangle_light};
|
use super::psy_light::{parse_sphere_light, parse_rectangle_light};
|
||||||
use super::psy_mesh_surface::parse_mesh_surface;
|
use super::psy_mesh_surface::parse_mesh_surface;
|
||||||
|
use super::psy_surface_shader::parse_surface_shader;
|
||||||
use super::psy::{parse_matrix, PsyParseError};
|
use super::psy::{parse_matrix, PsyParseError};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +46,22 @@ pub fn parse_assembly<'a>(
|
||||||
child.iter_leaf_children_with_type("Data").nth(0).unwrap().1
|
child.iter_leaf_children_with_type("Data").nth(0).unwrap().1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get surface shader binding, if any.
|
||||||
|
let surface_shader_name = if child
|
||||||
|
.iter_leaf_children_with_type("SurfaceShaderBind")
|
||||||
|
.count() > 0
|
||||||
|
{
|
||||||
|
Some(
|
||||||
|
child
|
||||||
|
.iter_leaf_children_with_type("SurfaceShaderBind")
|
||||||
|
.nth(0)
|
||||||
|
.unwrap()
|
||||||
|
.1,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// Get xforms
|
// Get xforms
|
||||||
let mut xforms = Vec::new();
|
let mut xforms = Vec::new();
|
||||||
for (_, contents, _) in child.iter_leaf_children_with_type("Transform") {
|
for (_, contents, _) in child.iter_leaf_children_with_type("Transform") {
|
||||||
|
@ -53,7 +70,7 @@ pub fn parse_assembly<'a>(
|
||||||
|
|
||||||
// Add instance
|
// Add instance
|
||||||
if builder.name_exists(name) {
|
if builder.name_exists(name) {
|
||||||
builder.add_instance(name, Some(&xforms));
|
builder.add_instance(name, surface_shader_name, Some(&xforms));
|
||||||
} else {
|
} else {
|
||||||
return Err(PsyParseError::InstancedMissingData(
|
return Err(PsyParseError::InstancedMissingData(
|
||||||
child.iter_leaf_children_with_type("Data").nth(0).unwrap().2,
|
child.iter_leaf_children_with_type("Data").nth(0).unwrap().2,
|
||||||
|
@ -66,6 +83,20 @@ pub fn parse_assembly<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SurfaceShader
|
||||||
|
"SurfaceShader" => {
|
||||||
|
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||||
|
builder.add_surface_shader(ident, parse_surface_shader(arena, child)?);
|
||||||
|
} else {
|
||||||
|
// TODO: error condition of some kind, because no ident
|
||||||
|
panic!(
|
||||||
|
"SurfaceShader encountered that was a leaf, but SurfaceShaders cannot \
|
||||||
|
be a leaf: {}",
|
||||||
|
child.byte_offset()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MeshSurface
|
// MeshSurface
|
||||||
"MeshSurface" => {
|
"MeshSurface" => {
|
||||||
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||||
|
@ -109,17 +140,6 @@ pub fn parse_assembly<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Surface shader
|
|
||||||
"SurfaceShader" => {
|
|
||||||
if let DataTree::Internal { ident: Some(_), .. } = *child {
|
|
||||||
// TODO
|
|
||||||
//unimplemented!()
|
|
||||||
} else {
|
|
||||||
// No ident
|
|
||||||
return Err(PsyParseError::UnknownError(child.byte_offset()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
// TODO: some kind of error, because not a known type name
|
// TODO: some kind of error, because not a known type name
|
||||||
}
|
}
|
||||||
|
@ -143,12 +163,6 @@ pub fn parse_assembly<'a>(
|
||||||
// else if (child.type == "Sphere") {
|
// else if (child.type == "Sphere") {
|
||||||
// assembly->add_object(child.name, parse_sphere(child));
|
// assembly->add_object(child.name, parse_sphere(child));
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// // Surface shader
|
|
||||||
// else if (child.type == "SurfaceShader") {
|
|
||||||
// assembly->add_surface_shader(child.name, parse_surface_shader(child));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
68
src/parse/psy_surface_shader.rs
Normal file
68
src/parse/psy_surface_shader.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
use mem_arena::MemArena;
|
||||||
|
|
||||||
|
use color::{XYZ, rec709_e_to_xyz};
|
||||||
|
use shading::{SurfaceShader, SimpleSurfaceShader};
|
||||||
|
|
||||||
|
use super::basics::ws_f32;
|
||||||
|
use super::DataTree;
|
||||||
|
use super::psy::PsyParseError;
|
||||||
|
|
||||||
|
|
||||||
|
// pub struct TriangleMesh {
|
||||||
|
// time_samples: usize,
|
||||||
|
// geo: Vec<(Point, Point, Point)>,
|
||||||
|
// indices: Vec<usize>,
|
||||||
|
// accel: BVH,
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn parse_surface_shader<'a>(
|
||||||
|
arena: &'a MemArena,
|
||||||
|
tree: &'a DataTree,
|
||||||
|
) -> Result<&'a SurfaceShader, PsyParseError> {
|
||||||
|
let type_name = if let Some((_, text, _)) = tree.iter_leaf_children_with_type("Type").nth(0) {
|
||||||
|
text.trim()
|
||||||
|
} else {
|
||||||
|
return Err(PsyParseError::MissingNode(
|
||||||
|
tree.byte_offset(),
|
||||||
|
"Expected a Type field in SurfaceShader.",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let shader = match type_name {
|
||||||
|
"Emit" => unimplemented!(),
|
||||||
|
"Lambert" => {
|
||||||
|
let color = if let Some((_, contents, byte_offset)) =
|
||||||
|
tree.iter_leaf_children_with_type("Color").nth(0)
|
||||||
|
{
|
||||||
|
if let IResult::Done(_, color) =
|
||||||
|
closure!(tuple!(ws_f32, ws_f32, ws_f32))(contents.as_bytes())
|
||||||
|
{
|
||||||
|
// TODO: handle color space conversions properly.
|
||||||
|
// Probably will need a special color type with its
|
||||||
|
// own parser...?
|
||||||
|
XYZ::from_tuple(rec709_e_to_xyz(color))
|
||||||
|
} else {
|
||||||
|
// Found color, but its contents is not in the right format
|
||||||
|
return Err(PsyParseError::UnknownError(byte_offset));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(PsyParseError::MissingNode(
|
||||||
|
tree.byte_offset(),
|
||||||
|
"Expected a Color field in Lambert SurfaceShader.",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
arena.alloc(SimpleSurfaceShader::Lambert { color: color })
|
||||||
|
}
|
||||||
|
"GTR" => unimplemented!(),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(shader)
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ use lerp::lerp_slice;
|
||||||
use light::LightSource;
|
use light::LightSource;
|
||||||
use math::{Matrix4x4, Vector};
|
use math::{Matrix4x4, Vector};
|
||||||
use surface::{Surface, SurfaceIntersection};
|
use surface::{Surface, SurfaceIntersection};
|
||||||
|
use shading::SurfaceShader;
|
||||||
use transform_stack::TransformStack;
|
use transform_stack::TransformStack;
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +22,9 @@ pub struct Assembly<'a> {
|
||||||
pub light_instances: &'a [Instance],
|
pub light_instances: &'a [Instance],
|
||||||
pub xforms: &'a [Matrix4x4],
|
pub xforms: &'a [Matrix4x4],
|
||||||
|
|
||||||
|
// Surface shader list
|
||||||
|
pub surface_shaders: &'a [&'a SurfaceShader],
|
||||||
|
|
||||||
// Object list
|
// Object list
|
||||||
pub objects: &'a [Object<'a>],
|
pub objects: &'a [Object<'a>],
|
||||||
|
|
||||||
|
@ -150,6 +154,10 @@ pub struct AssemblyBuilder<'a> {
|
||||||
instances: Vec<Instance>,
|
instances: Vec<Instance>,
|
||||||
xforms: Vec<Matrix4x4>,
|
xforms: Vec<Matrix4x4>,
|
||||||
|
|
||||||
|
// Shader list
|
||||||
|
surface_shaders: Vec<&'a SurfaceShader>,
|
||||||
|
surface_shader_map: HashMap<String, usize>, // map Name -> Index
|
||||||
|
|
||||||
// Object list
|
// Object list
|
||||||
objects: Vec<Object<'a>>,
|
objects: Vec<Object<'a>>,
|
||||||
object_map: HashMap<String, usize>, // map Name -> Index
|
object_map: HashMap<String, usize>, // map Name -> Index
|
||||||
|
@ -166,6 +174,8 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
arena: arena,
|
arena: arena,
|
||||||
instances: Vec::new(),
|
instances: Vec::new(),
|
||||||
xforms: Vec::new(),
|
xforms: Vec::new(),
|
||||||
|
surface_shaders: Vec::new(),
|
||||||
|
surface_shader_map: HashMap::new(),
|
||||||
objects: Vec::new(),
|
objects: Vec::new(),
|
||||||
object_map: HashMap::new(),
|
object_map: HashMap::new(),
|
||||||
assemblies: Vec::new(),
|
assemblies: Vec::new(),
|
||||||
|
@ -173,6 +183,20 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_surface_shader(&mut self, name: &str, shader: &'a SurfaceShader) {
|
||||||
|
// Make sure the name hasn't already been used.
|
||||||
|
if self.surface_shader_map.contains_key(name) {
|
||||||
|
panic!("Attempted to add surface shader to assembly with a name that already exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add shader
|
||||||
|
self.surface_shader_map.insert(
|
||||||
|
name.to_string(),
|
||||||
|
self.surface_shaders.len(),
|
||||||
|
);
|
||||||
|
self.surface_shaders.push(shader);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_object(&mut self, name: &str, obj: Object<'a>) {
|
pub fn add_object(&mut self, name: &str, obj: Object<'a>) {
|
||||||
// Make sure the name hasn't already been used.
|
// Make sure the name hasn't already been used.
|
||||||
if self.name_exists(name) {
|
if self.name_exists(name) {
|
||||||
|
@ -201,7 +225,12 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
self.assemblies.push(asmb);
|
self.assemblies.push(asmb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_instance(&mut self, name: &str, xforms: Option<&[Matrix4x4]>) {
|
pub fn add_instance(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
surface_shader_name: Option<&str>,
|
||||||
|
xforms: Option<&[Matrix4x4]>,
|
||||||
|
) {
|
||||||
// Make sure name exists
|
// Make sure name exists
|
||||||
if !self.name_exists(name) {
|
if !self.name_exists(name) {
|
||||||
panic!("Attempted to add instance with a name that doesn't exist.");
|
panic!("Attempted to add instance with a name that doesn't exist.");
|
||||||
|
@ -219,6 +248,12 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
Instance {
|
Instance {
|
||||||
instance_type: InstanceType::Object,
|
instance_type: InstanceType::Object,
|
||||||
data_index: self.object_map[name],
|
data_index: self.object_map[name],
|
||||||
|
surface_shader_index: surface_shader_name.map(|name| {
|
||||||
|
*self.surface_shader_map.get(name).expect(&format!(
|
||||||
|
"Unknown surface shader '{}'.",
|
||||||
|
name
|
||||||
|
))
|
||||||
|
}),
|
||||||
id: self.instances.len(),
|
id: self.instances.len(),
|
||||||
transform_indices: xforms.map(
|
transform_indices: xforms.map(
|
||||||
|xf| (self.xforms.len(), self.xforms.len() + xf.len()),
|
|xf| (self.xforms.len(), self.xforms.len() + xf.len()),
|
||||||
|
@ -228,6 +263,12 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
Instance {
|
Instance {
|
||||||
instance_type: InstanceType::Assembly,
|
instance_type: InstanceType::Assembly,
|
||||||
data_index: self.assembly_map[name],
|
data_index: self.assembly_map[name],
|
||||||
|
surface_shader_index: surface_shader_name.map(|name| {
|
||||||
|
*self.surface_shader_map.get(name).expect(&format!(
|
||||||
|
"Unknown surface shader '{}'.",
|
||||||
|
name
|
||||||
|
))
|
||||||
|
}),
|
||||||
id: self.instances.len(),
|
id: self.instances.len(),
|
||||||
transform_indices: xforms.map(
|
transform_indices: xforms.map(
|
||||||
|xf| (self.xforms.len(), self.xforms.len() + xf.len()),
|
|xf| (self.xforms.len(), self.xforms.len() + xf.len()),
|
||||||
|
@ -303,6 +344,7 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
instances: self.arena.copy_slice(&self.instances),
|
instances: self.arena.copy_slice(&self.instances),
|
||||||
light_instances: self.arena.copy_slice(&light_instances),
|
light_instances: self.arena.copy_slice(&light_instances),
|
||||||
xforms: self.arena.copy_slice(&self.xforms),
|
xforms: self.arena.copy_slice(&self.xforms),
|
||||||
|
surface_shaders: self.arena.copy_slice(&self.surface_shaders),
|
||||||
objects: self.arena.copy_slice(&self.objects),
|
objects: self.arena.copy_slice(&self.objects),
|
||||||
assemblies: self.arena.copy_slice(&self.assemblies),
|
assemblies: self.arena.copy_slice(&self.assemblies),
|
||||||
object_accel: object_accel,
|
object_accel: object_accel,
|
||||||
|
@ -370,6 +412,7 @@ pub enum Object<'a> {
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
pub instance_type: InstanceType,
|
pub instance_type: InstanceType,
|
||||||
pub data_index: usize,
|
pub data_index: usize,
|
||||||
|
pub surface_shader_index: Option<usize>,
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
pub transform_indices: Option<(usize, usize)>,
|
pub transform_indices: Option<(usize, usize)>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use self::surface_closure::{SurfaceClosureUnion, EmitClosure, LambertClosure, GT
|
||||||
use surface::SurfaceIntersectionData;
|
use surface::SurfaceIntersectionData;
|
||||||
|
|
||||||
/// Trait for surface shaders.
|
/// Trait for surface shaders.
|
||||||
pub trait SurfaceShader: Debug {
|
pub trait SurfaceShader: Debug + Sync {
|
||||||
/// Takes the result of a surface intersection and returns the surface
|
/// Takes the result of a surface intersection and returns the surface
|
||||||
/// closure to be evaluated at that intersection point.
|
/// closure to be evaluated at that intersection point.
|
||||||
fn shade(&self, data: &SurfaceIntersectionData, wavelength: f32) -> SurfaceClosureUnion;
|
fn shade(&self, data: &SurfaceIntersectionData, wavelength: f32) -> SurfaceClosureUnion;
|
||||||
|
@ -24,7 +24,7 @@ pub trait SurfaceShader: Debug {
|
||||||
/// are no ordinary donuts. To call them large is actually doing
|
/// are no ordinary donuts. To call them large is actually doing
|
||||||
/// them a great injustice, for they are each the size of a small
|
/// them a great injustice, for they are each the size of a small
|
||||||
/// building.
|
/// building.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum SimpleSurfaceShader {
|
pub enum SimpleSurfaceShader {
|
||||||
Emit { color: XYZ },
|
Emit { color: XYZ },
|
||||||
Lambert { color: XYZ },
|
Lambert { color: XYZ },
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::fmt::Debug;
|
||||||
use boundable::Boundable;
|
use boundable::Boundable;
|
||||||
use math::{Point, Vector, Normal, Matrix4x4};
|
use math::{Point, Vector, Normal, Matrix4x4};
|
||||||
use ray::{Ray, AccelRay};
|
use ray::{Ray, AccelRay};
|
||||||
|
use shading::SurfaceShader;
|
||||||
use shading::surface_closure::SurfaceClosureUnion;
|
use shading::surface_closure::SurfaceClosureUnion;
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ pub trait Surface: Boundable + Debug + Sync {
|
||||||
accel_rays: &mut [AccelRay],
|
accel_rays: &mut [AccelRay],
|
||||||
wrays: &[Ray],
|
wrays: &[Ray],
|
||||||
isects: &mut [SurfaceIntersection],
|
isects: &mut [SurfaceIntersection],
|
||||||
|
shader: &SurfaceShader,
|
||||||
space: &[Matrix4x4],
|
space: &[Matrix4x4],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,11 @@ use mem_arena::MemArena;
|
||||||
use accel::BVH4;
|
use accel::BVH4;
|
||||||
use bbox::BBox;
|
use bbox::BBox;
|
||||||
use boundable::Boundable;
|
use boundable::Boundable;
|
||||||
use color::XYZ;
|
|
||||||
use fp_utils::fp_gamma;
|
use fp_utils::fp_gamma;
|
||||||
use lerp::lerp_slice;
|
use lerp::lerp_slice;
|
||||||
use math::{Point, Normal, Matrix4x4, dot, cross};
|
use math::{Point, Normal, Matrix4x4, dot, cross};
|
||||||
use ray::{Ray, AccelRay};
|
use ray::{Ray, AccelRay};
|
||||||
use shading::{SurfaceShader, SimpleSurfaceShader};
|
use shading::SurfaceShader;
|
||||||
|
|
||||||
use super::{Surface, SurfaceIntersection, SurfaceIntersectionData};
|
use super::{Surface, SurfaceIntersection, SurfaceIntersectionData};
|
||||||
use super::triangle;
|
use super::triangle;
|
||||||
|
@ -123,6 +122,7 @@ impl<'a> Surface for TriangleMesh<'a> {
|
||||||
accel_rays: &mut [AccelRay],
|
accel_rays: &mut [AccelRay],
|
||||||
wrays: &[Ray],
|
wrays: &[Ray],
|
||||||
isects: &mut [SurfaceIntersection],
|
isects: &mut [SurfaceIntersection],
|
||||||
|
shader: &SurfaceShader,
|
||||||
space: &[Matrix4x4],
|
space: &[Matrix4x4],
|
||||||
) {
|
) {
|
||||||
// Precalculate transform for non-motion blur cases
|
// Precalculate transform for non-motion blur cases
|
||||||
|
@ -249,16 +249,7 @@ impl<'a> Surface for TriangleMesh<'a> {
|
||||||
// Fill in intersection data
|
// Fill in intersection data
|
||||||
isects[r.id as usize] = SurfaceIntersection::Hit {
|
isects[r.id as usize] = SurfaceIntersection::Hit {
|
||||||
intersection_data: intersection_data,
|
intersection_data: intersection_data,
|
||||||
// TODO: get surface shader from user-defined shader.
|
closure: shader.shade(&intersection_data, wr.wavelength),
|
||||||
closure: SimpleSurfaceShader::Lambert {
|
|
||||||
color: XYZ::new(0.8, 0.8, 0.8),
|
|
||||||
}.shade(&intersection_data, wr.wavelength),
|
|
||||||
// closure: SimpleSurfaceShader::GTR {
|
|
||||||
// color: XYZ::new(0.8, 0.8, 0.8),
|
|
||||||
// roughness: 0.1,
|
|
||||||
// tail_shape: 2.0,
|
|
||||||
// fresnel: 1.0,
|
|
||||||
// }.shade(&intersection_data, wr.wavelength),
|
|
||||||
};
|
};
|
||||||
r.max_t = t;
|
r.max_t = t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ use ray::{Ray, AccelRay};
|
||||||
use scene::{Assembly, Object, InstanceType};
|
use scene::{Assembly, Object, InstanceType};
|
||||||
use surface::SurfaceIntersection;
|
use surface::SurfaceIntersection;
|
||||||
use transform_stack::TransformStack;
|
use transform_stack::TransformStack;
|
||||||
|
use shading::{SurfaceShader, SimpleSurfaceShader};
|
||||||
|
use color::XYZ;
|
||||||
|
|
||||||
|
|
||||||
pub struct Tracer<'a> {
|
pub struct Tracer<'a> {
|
||||||
|
@ -128,6 +130,9 @@ impl<'a> TracerInner<'a> {
|
||||||
InstanceType::Object => {
|
InstanceType::Object => {
|
||||||
self.trace_object(
|
self.trace_object(
|
||||||
&assembly.objects[inst.data_index],
|
&assembly.objects[inst.data_index],
|
||||||
|
inst.surface_shader_index.map(
|
||||||
|
|i| assembly.surface_shaders[i],
|
||||||
|
),
|
||||||
wrays,
|
wrays,
|
||||||
ray_set,
|
ray_set,
|
||||||
);
|
);
|
||||||
|
@ -171,10 +176,26 @@ impl<'a> TracerInner<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace_object<'b>(&'b mut self, obj: &Object, wrays: &[Ray], rays: &mut [AccelRay]) {
|
fn trace_object<'b>(
|
||||||
|
&'b mut self,
|
||||||
|
obj: &Object,
|
||||||
|
surface_shader: Option<&SurfaceShader>,
|
||||||
|
wrays: &[Ray],
|
||||||
|
rays: &mut [AccelRay],
|
||||||
|
) {
|
||||||
match *obj {
|
match *obj {
|
||||||
Object::Surface(surface) => {
|
Object::Surface(surface) => {
|
||||||
surface.intersect_rays(rays, wrays, &mut self.isects, self.xform_stack.top());
|
let unassigned_shader =
|
||||||
|
SimpleSurfaceShader::Lambert { color: XYZ::new(1.0, 0.0, 1.0) };
|
||||||
|
let shader = surface_shader.unwrap_or(&unassigned_shader);
|
||||||
|
|
||||||
|
surface.intersect_rays(
|
||||||
|
rays,
|
||||||
|
wrays,
|
||||||
|
&mut self.isects,
|
||||||
|
shader,
|
||||||
|
self.xform_stack.top(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Light(_) => {
|
Object::Light(_) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user