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.objects = []
|
||||||
self.instances = []
|
self.instances = []
|
||||||
|
|
||||||
|
self.material_names = set()
|
||||||
self.mesh_names = set()
|
self.mesh_names = set()
|
||||||
self.assembly_names = set()
|
self.assembly_names = set()
|
||||||
|
|
||||||
|
@ -119,10 +120,19 @@ class Assembly:
|
||||||
if should_export_mesh:
|
if should_export_mesh:
|
||||||
self.mesh_names.add(mesh_name)
|
self.mesh_names.add(mesh_name)
|
||||||
self.objects += [Mesh(self.render_engine, ob, 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
|
return mesh_name
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_sphere_lamp(self, ob, group_prefix):
|
def get_sphere_lamp(self, ob, group_prefix):
|
||||||
name = group_prefix + "__" + escape_name(ob.name)
|
name = group_prefix + "__" + escape_name(ob.name)
|
||||||
self.objects += [SphereLamp(self.render_engine, ob, name)]
|
self.objects += [SphereLamp(self.render_engine, ob, name)]
|
||||||
|
@ -281,5 +291,46 @@ class Instance:
|
||||||
w.write("Data [$%s]\n" % self.data_name)
|
w.write("Data [$%s]\n" % self.data_name)
|
||||||
for mat in self.time_xforms:
|
for mat in self.time_xforms:
|
||||||
w.write("Transform [%s]\n" % mat2str(mat.inverted()))
|
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.unindent()
|
||||||
w.write("}\n")
|
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 {
|
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" => {
|
"Lambert" => {
|
||||||
let color = if let Some((_, contents, byte_offset)) =
|
let color = if let Some((_, contents, byte_offset)) =
|
||||||
tree.iter_leaf_children_with_type("Color").nth(0)
|
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 })
|
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!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use scene::{Assembly, Object, InstanceType};
|
||||||
use surface::SurfaceIntersection;
|
use surface::SurfaceIntersection;
|
||||||
use transform_stack::TransformStack;
|
use transform_stack::TransformStack;
|
||||||
use shading::{SurfaceShader, SimpleSurfaceShader};
|
use shading::{SurfaceShader, SimpleSurfaceShader};
|
||||||
use color::XYZ;
|
use color::{XYZ, rec709_to_xyz};
|
||||||
|
|
||||||
|
|
||||||
pub struct Tracer<'a> {
|
pub struct Tracer<'a> {
|
||||||
|
@ -185,8 +185,9 @@ impl<'a> TracerInner<'a> {
|
||||||
) {
|
) {
|
||||||
match *obj {
|
match *obj {
|
||||||
Object::Surface(surface) => {
|
Object::Surface(surface) => {
|
||||||
let unassigned_shader =
|
let unassigned_shader = SimpleSurfaceShader::Lambert {
|
||||||
SimpleSurfaceShader::Lambert { color: XYZ::new(1.0, 0.0, 1.0) };
|
color: XYZ::from_tuple(rec709_to_xyz((1.0, 0.0, 1.0))),
|
||||||
|
};
|
||||||
let shader = surface_shader.unwrap_or(&unassigned_shader);
|
let shader = surface_shader.unwrap_or(&unassigned_shader);
|
||||||
|
|
||||||
surface.intersect_rays(
|
surface.intersect_rays(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user