Materials are now working in both Psychopath and PsychoBlend.
Except that Emit is still not properly supported, because it needs special handling.
This commit is contained in:
parent
516803e78a
commit
ad55aa4f6d
|
@ -12,6 +12,7 @@ class Assembly:
|
|||
self.objects = []
|
||||
self.instances = []
|
||||
|
||||
self.material_names = set()
|
||||
self.mesh_names = set()
|
||||
self.assembly_names = set()
|
||||
|
||||
|
@ -119,10 +120,19 @@ class Assembly:
|
|||
if should_export_mesh:
|
||||
self.mesh_names.add(mesh_name)
|
||||
self.objects += [Mesh(self.render_engine, ob, mesh_name)]
|
||||
|
||||
# Get materials
|
||||
for ms in ob.material_slots:
|
||||
if ms != None:
|
||||
if ms.material.name not in self.material_names:
|
||||
self.material_names.add(ms.material.name)
|
||||
self.materials += [Material(self.render_engine, ms.material)]
|
||||
|
||||
return mesh_name
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_sphere_lamp(self, ob, group_prefix):
|
||||
name = group_prefix + "__" + escape_name(ob.name)
|
||||
self.objects += [SphereLamp(self.render_engine, ob, name)]
|
||||
|
@ -281,5 +291,46 @@ class Instance:
|
|||
w.write("Data [$%s]\n" % self.data_name)
|
||||
for mat in self.time_xforms:
|
||||
w.write("Transform [%s]\n" % mat2str(mat.inverted()))
|
||||
for ms in self.ob.material_slots:
|
||||
if ms != None:
|
||||
w.write("SurfaceShaderBind [$%s]\n" % escape_name(ms.material.name))
|
||||
break
|
||||
w.unindent()
|
||||
w.write("}\n")
|
||||
|
||||
|
||||
class Material:
|
||||
def __init__(self, render_engine, material):
|
||||
self.mat = material
|
||||
|
||||
def take_sample(self, render_engine, time, translation_offset):
|
||||
# TODO: motion blur of material settings
|
||||
pass
|
||||
|
||||
def export(self, render_engine, w):
|
||||
render_engine.update_stats("", "Psychopath: Exporting %s" % self.mat.name)
|
||||
|
||||
w.write("SurfaceShader $%s {\n" % escape_name(self.mat.name))
|
||||
w.indent()
|
||||
if self.mat.psychopath.surface_shader_type == 'Emit':
|
||||
w.write("Type [Emit]\n")
|
||||
color = self.mat.psychopath.color
|
||||
w.write("Color [%f %f %f]\n" % (color[0], color[1], color[2]))
|
||||
elif self.mat.psychopath.surface_shader_type == 'Lambert':
|
||||
w.write("Type [Lambert]\n")
|
||||
color = self.mat.psychopath.color
|
||||
w.write("Color [%f %f %f]\n" % (color[0], color[1], color[2]))
|
||||
elif self.mat.psychopath.surface_shader_type == 'GTR':
|
||||
w.write("Type [GTR]\n")
|
||||
color = self.mat.psychopath.color
|
||||
w.write("Color [%f %f %f]\n" % (color[0], color[1], color[2]))
|
||||
w.write("Roughness [%f]\n" % self.mat.psychopath.roughness)
|
||||
w.write("TailShape [%f]\n" % self.mat.psychopath.tail_shape)
|
||||
w.write("Fresnel [%f]\n" % self.mat.psychopath.fresnel)
|
||||
else:
|
||||
raise "Unsupported surface shader type '%s'" % self.mat.psychopath.surface_shader_type
|
||||
w.unindent()
|
||||
w.write("}\n")
|
||||
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
|
|
@ -35,7 +35,30 @@ pub fn parse_surface_shader<'a>(
|
|||
};
|
||||
|
||||
let shader = match type_name {
|
||||
"Emit" => unimplemented!(),
|
||||
"Emit" => {
|
||||
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 Emit SurfaceShader.",
|
||||
));
|
||||
};
|
||||
|
||||
arena.alloc(SimpleSurfaceShader::Emit { color: color })
|
||||
}
|
||||
"Lambert" => {
|
||||
let color = if let Some((_, contents, byte_offset)) =
|
||||
tree.iter_leaf_children_with_type("Color").nth(0)
|
||||
|
@ -60,7 +83,84 @@ pub fn parse_surface_shader<'a>(
|
|||
|
||||
arena.alloc(SimpleSurfaceShader::Lambert { color: color })
|
||||
}
|
||||
"GTR" => unimplemented!(),
|
||||
"GTR" => {
|
||||
// Color
|
||||
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 GTR SurfaceShader.",
|
||||
));
|
||||
};
|
||||
|
||||
// Roughness
|
||||
let roughness = if let Some((_, contents, byte_offset)) =
|
||||
tree.iter_leaf_children_with_type("Roughness").nth(0)
|
||||
{
|
||||
if let IResult::Done(_, roughness) = ws_f32(contents.as_bytes()) {
|
||||
roughness
|
||||
} else {
|
||||
return Err(PsyParseError::UnknownError(byte_offset));
|
||||
}
|
||||
} else {
|
||||
return Err(PsyParseError::MissingNode(
|
||||
tree.byte_offset(),
|
||||
"Expected a Roughness field in GTR SurfaceShader.",
|
||||
));
|
||||
};
|
||||
|
||||
// TailShape
|
||||
let tail_shape = if let Some((_, contents, byte_offset)) =
|
||||
tree.iter_leaf_children_with_type("TailShape").nth(0)
|
||||
{
|
||||
if let IResult::Done(_, tail_shape) = ws_f32(contents.as_bytes()) {
|
||||
tail_shape
|
||||
} else {
|
||||
return Err(PsyParseError::UnknownError(byte_offset));
|
||||
}
|
||||
} else {
|
||||
return Err(PsyParseError::MissingNode(
|
||||
tree.byte_offset(),
|
||||
"Expected a TailShape field in GTR SurfaceShader.",
|
||||
));
|
||||
};
|
||||
|
||||
// Fresnel
|
||||
let fresnel = if let Some((_, contents, byte_offset)) =
|
||||
tree.iter_leaf_children_with_type("Fresnel").nth(0)
|
||||
{
|
||||
if let IResult::Done(_, fresnel) = ws_f32(contents.as_bytes()) {
|
||||
fresnel
|
||||
} else {
|
||||
return Err(PsyParseError::UnknownError(byte_offset));
|
||||
}
|
||||
} else {
|
||||
return Err(PsyParseError::MissingNode(
|
||||
tree.byte_offset(),
|
||||
"Expected a Fresnel field in GTR SurfaceShader.",
|
||||
));
|
||||
};
|
||||
|
||||
arena.alloc(SimpleSurfaceShader::GTR {
|
||||
color: color,
|
||||
roughness: roughness,
|
||||
tail_shape: tail_shape,
|
||||
fresnel: fresnel,
|
||||
})
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use scene::{Assembly, Object, InstanceType};
|
|||
use surface::SurfaceIntersection;
|
||||
use transform_stack::TransformStack;
|
||||
use shading::{SurfaceShader, SimpleSurfaceShader};
|
||||
use color::XYZ;
|
||||
use color::{XYZ, rec709_to_xyz};
|
||||
|
||||
|
||||
pub struct Tracer<'a> {
|
||||
|
@ -185,8 +185,9 @@ impl<'a> TracerInner<'a> {
|
|||
) {
|
||||
match *obj {
|
||||
Object::Surface(surface) => {
|
||||
let unassigned_shader =
|
||||
SimpleSurfaceShader::Lambert { color: XYZ::new(1.0, 0.0, 1.0) };
|
||||
let unassigned_shader = SimpleSurfaceShader::Lambert {
|
||||
color: XYZ::from_tuple(rec709_to_xyz((1.0, 0.0, 1.0))),
|
||||
};
|
||||
let shader = surface_shader.unwrap_or(&unassigned_shader);
|
||||
|
||||
surface.intersect_rays(
|
||||
|
|
Loading…
Reference in New Issue
Block a user