Made samples per bucket configurable.
This commit is contained in:
parent
bb4e57795f
commit
0e8d708ff0
|
@ -40,6 +40,11 @@ class RenderPsychopathSettingsScene(PropertyGroup):
|
||||||
min=1, max=65536, default=16
|
min=1, max=65536, default=16
|
||||||
)
|
)
|
||||||
|
|
||||||
|
max_samples_per_bucket = IntProperty(
|
||||||
|
name="Max Samples Per Bucket", description="How many samples to simultaneously calculate per thread; indirectly determines bucket size",
|
||||||
|
min=1, max=2**28, soft_max=2**16, default=4096
|
||||||
|
)
|
||||||
|
|
||||||
dicing_rate = FloatProperty(
|
dicing_rate = FloatProperty(
|
||||||
name="Dicing Rate", description="The target microgeometry width in pixels",
|
name="Dicing Rate", description="The target microgeometry width in pixels",
|
||||||
min=0.0001, max=100.0, soft_min=0.125, soft_max=1.0, default=0.25
|
min=0.0001, max=100.0, soft_min=0.125, soft_max=1.0, default=0.25
|
||||||
|
@ -86,24 +91,24 @@ class PsychopathMaterial(bpy.types.PropertyGroup):
|
||||||
items=[('Emit', 'Emit', ""), ('Lambert', 'Lambert', ""), ('GTR', 'GTR', "")],
|
items=[('Emit', 'Emit', ""), ('Lambert', 'Lambert', ""), ('GTR', 'GTR', "")],
|
||||||
default="Lambert"
|
default="Lambert"
|
||||||
)
|
)
|
||||||
|
|
||||||
color = FloatVectorProperty(
|
color = FloatVectorProperty(
|
||||||
name="Color", description="",
|
name="Color", description="",
|
||||||
subtype='COLOR',
|
subtype='COLOR',
|
||||||
min=0.0, soft_min=0.0, soft_max = 1.0,
|
min=0.0, soft_min=0.0, soft_max = 1.0,
|
||||||
default=[0.8,0.8,0.8]
|
default=[0.8,0.8,0.8]
|
||||||
)
|
)
|
||||||
|
|
||||||
roughness = FloatProperty(
|
roughness = FloatProperty(
|
||||||
name="Roughness", description="",
|
name="Roughness", description="",
|
||||||
min=-1.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.1
|
min=-1.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
tail_shape = FloatProperty(
|
tail_shape = FloatProperty(
|
||||||
name="Tail Shape", description="",
|
name="Tail Shape", description="",
|
||||||
min=0.0, max=8.0, soft_min=1.0, soft_max=3.0, default=2.0
|
min=0.0, max=8.0, soft_min=1.0, soft_max=3.0, default=2.0
|
||||||
)
|
)
|
||||||
|
|
||||||
fresnel = FloatProperty(
|
fresnel = FloatProperty(
|
||||||
name="Fresnel", description="",
|
name="Fresnel", description="",
|
||||||
min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.9
|
min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.9
|
||||||
|
|
|
@ -49,7 +49,7 @@ class PsychopathRender(bpy.types.RenderEngine):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# TODO: figure out command line options
|
# TODO: figure out command line options
|
||||||
args = ["-i", psy_filepath]
|
args = ["--spb", str(scene.psychopath.max_samples_per_bucket), "-i", psy_filepath]
|
||||||
|
|
||||||
# Start Rendering!
|
# Start Rendering!
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -46,6 +46,9 @@ class RENDER_PT_psychopath_render_settings(PsychopathPanel, bpy.types.Panel):
|
||||||
col.prop(scene.psychopath, "shutter_start")
|
col.prop(scene.psychopath, "shutter_start")
|
||||||
col.prop(scene.psychopath, "shutter_end")
|
col.prop(scene.psychopath, "shutter_end")
|
||||||
|
|
||||||
|
col.label(text="Performance")
|
||||||
|
col.prop(scene.psychopath, "max_samples_per_bucket")
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_psychopath_export_settings(PsychopathPanel, bpy.types.Panel):
|
class RENDER_PT_psychopath_export_settings(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_label = "Export Settings"
|
bl_label = "Export Settings"
|
||||||
|
@ -66,14 +69,14 @@ class WORLD_PT_psychopath_background(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_space_type = 'PROPERTIES'
|
bl_space_type = 'PROPERTIES'
|
||||||
bl_region_type = 'WINDOW'
|
bl_region_type = 'WINDOW'
|
||||||
bl_context = "world"
|
bl_context = "world"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return context.world and PsychopathPanel.poll(context)
|
return context.world and PsychopathPanel.poll(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
world = context.world
|
world = context.world
|
||||||
layout.prop(world, "horizon_color", text="Color")
|
layout.prop(world, "horizon_color", text="Color")
|
||||||
|
|
||||||
|
@ -131,22 +134,22 @@ class DATA_PT_psychopath_area_lamp(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_space_type = 'PROPERTIES'
|
bl_space_type = 'PROPERTIES'
|
||||||
bl_region_type = 'WINDOW'
|
bl_region_type = 'WINDOW'
|
||||||
bl_context = "data"
|
bl_context = "data"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
lamp = context.lamp
|
lamp = context.lamp
|
||||||
engine = context.scene.render.engine
|
engine = context.scene.render.engine
|
||||||
return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
|
return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
lamp = context.lamp
|
lamp = context.lamp
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.row().prop(lamp, "shape", expand=True)
|
col.row().prop(lamp, "shape", expand=True)
|
||||||
sub = col.row(align=True)
|
sub = col.row(align=True)
|
||||||
|
|
||||||
if lamp.shape == 'SQUARE':
|
if lamp.shape == 'SQUARE':
|
||||||
sub.prop(lamp, "size")
|
sub.prop(lamp, "size")
|
||||||
elif lamp.shape == 'RECTANGLE':
|
elif lamp.shape == 'RECTANGLE':
|
||||||
|
@ -159,19 +162,19 @@ class DATA_PT_psychopath_mesh(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_space_type = 'PROPERTIES'
|
bl_space_type = 'PROPERTIES'
|
||||||
bl_region_type = 'WINDOW'
|
bl_region_type = 'WINDOW'
|
||||||
bl_context = "data"
|
bl_context = "data"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
engine = context.scene.render.engine
|
engine = context.scene.render.engine
|
||||||
return context.mesh and (engine in cls.COMPAT_ENGINES)
|
return context.mesh and (engine in cls.COMPAT_ENGINES)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
mesh = context.mesh
|
mesh = context.mesh
|
||||||
|
|
||||||
layout.row().prop(mesh.psychopath, "is_subdivision_surface")
|
layout.row().prop(mesh.psychopath, "is_subdivision_surface")
|
||||||
|
|
||||||
|
|
||||||
class MATERIAL_PT_psychopath_context_material(PsychopathPanel, bpy.types.Panel):
|
class MATERIAL_PT_psychopath_context_material(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_label = ""
|
bl_label = ""
|
||||||
|
@ -179,42 +182,42 @@ class MATERIAL_PT_psychopath_context_material(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_region_type = "WINDOW"
|
bl_region_type = "WINDOW"
|
||||||
bl_context = "material"
|
bl_context = "material"
|
||||||
bl_options = {'HIDE_HEADER'}
|
bl_options = {'HIDE_HEADER'}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return (context.material or context.object) and PsychopathPanel.poll(context)
|
return (context.material or context.object) and PsychopathPanel.poll(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
mat = context.material
|
mat = context.material
|
||||||
ob = context.object
|
ob = context.object
|
||||||
slot = context.material_slot
|
slot = context.material_slot
|
||||||
space = context.space_data
|
space = context.space_data
|
||||||
|
|
||||||
if ob:
|
if ob:
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)
|
row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)
|
||||||
|
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
|
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
|
||||||
col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
|
col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
|
||||||
|
|
||||||
col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
|
col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
|
||||||
|
|
||||||
if ob.mode == 'EDIT':
|
if ob.mode == 'EDIT':
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator("object.material_slot_assign", text="Assign")
|
row.operator("object.material_slot_assign", text="Assign")
|
||||||
row.operator("object.material_slot_select", text="Select")
|
row.operator("object.material_slot_select", text="Select")
|
||||||
row.operator("object.material_slot_deselect", text="Deselect")
|
row.operator("object.material_slot_deselect", text="Deselect")
|
||||||
|
|
||||||
split = layout.split(percentage=0.65)
|
split = layout.split(percentage=0.65)
|
||||||
|
|
||||||
if ob:
|
if ob:
|
||||||
split.template_ID(ob, "active_material", new="material.new")
|
split.template_ID(ob, "active_material", new="material.new")
|
||||||
row = split.row()
|
row = split.row()
|
||||||
|
|
||||||
if slot:
|
if slot:
|
||||||
row.prop(slot, "link", text="")
|
row.prop(slot, "link", text="")
|
||||||
else:
|
else:
|
||||||
|
@ -229,18 +232,18 @@ class MATERIAL_PT_psychopath_surface(PsychopathPanel, bpy.types.Panel):
|
||||||
bl_space_type = "PROPERTIES"
|
bl_space_type = "PROPERTIES"
|
||||||
bl_region_type = "WINDOW"
|
bl_region_type = "WINDOW"
|
||||||
bl_context = "material"
|
bl_context = "material"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return context.material and PsychopathPanel.poll(context)
|
return context.material and PsychopathPanel.poll(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
mat = context.material
|
mat = context.material
|
||||||
layout.prop(mat.psychopath, "surface_shader_type")
|
layout.prop(mat.psychopath, "surface_shader_type")
|
||||||
layout.prop(mat.psychopath, "color")
|
layout.prop(mat.psychopath, "color")
|
||||||
|
|
||||||
if mat.psychopath.surface_shader_type == 'GTR':
|
if mat.psychopath.surface_shader_type == 'GTR':
|
||||||
layout.prop(mat.psychopath, "roughness")
|
layout.prop(mat.psychopath, "roughness")
|
||||||
layout.prop(mat.psychopath, "tail_shape")
|
layout.prop(mat.psychopath, "tail_shape")
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -72,6 +72,7 @@ Usage:
|
||||||
Options:
|
Options:
|
||||||
-i <file>, --input <file> Input .psy file.
|
-i <file>, --input <file> Input .psy file.
|
||||||
-s <n>, --spp <n> Number of samples per pixel.
|
-s <n>, --spp <n> Number of samples per pixel.
|
||||||
|
-b <n>, --spb <n> Maxmimum number of samples per bucket (determines bucket size).
|
||||||
-t <n>, --threads <n> Number of threads to render with. Defaults
|
-t <n>, --threads <n> Number of threads to render with. Defaults
|
||||||
to the number of logical cores on the system.
|
to the number of logical cores on the system.
|
||||||
--dev Show useful dev/debug info.
|
--dev Show useful dev/debug info.
|
||||||
|
@ -83,6 +84,7 @@ Options:
|
||||||
struct Args {
|
struct Args {
|
||||||
flag_input: Option<String>,
|
flag_input: Option<String>,
|
||||||
flag_spp: Option<usize>,
|
flag_spp: Option<usize>,
|
||||||
|
flag_spb: Option<usize>,
|
||||||
flag_threads: Option<usize>,
|
flag_threads: Option<usize>,
|
||||||
flag_dev: bool,
|
flag_dev: bool,
|
||||||
flag_version: bool,
|
flag_version: bool,
|
||||||
|
@ -141,6 +143,12 @@ fn main() {
|
||||||
r.spp = spp;
|
r.spp = spp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let max_samples_per_bucket = if let Some(max_samples_per_bucket) = args.flag_spb {
|
||||||
|
max_samples_per_bucket as u32
|
||||||
|
} else {
|
||||||
|
4096
|
||||||
|
};
|
||||||
|
|
||||||
let thread_count = if let Some(threads) = args.flag_threads {
|
let thread_count = if let Some(threads) = args.flag_threads {
|
||||||
threads as u32
|
threads as u32
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,7 +158,7 @@ fn main() {
|
||||||
println!("\tBuilt scene in {:.3}s", t.tick());
|
println!("\tBuilt scene in {:.3}s", t.tick());
|
||||||
|
|
||||||
println!("Rendering scene with {} threads...", thread_count);
|
println!("Rendering scene with {} threads...", thread_count);
|
||||||
let mut image = r.render(thread_count);
|
let mut image = r.render(max_samples_per_bucket, thread_count);
|
||||||
println!("\tRendered scene in {:.3}s", t.tick());
|
println!("\tRendered scene in {:.3}s", t.tick());
|
||||||
|
|
||||||
println!("Writing image to disk...");
|
println!("Writing image to disk...");
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub struct Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
pub fn render(&self, thread_count: u32) -> Image {
|
pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> Image {
|
||||||
let mut tpool = Pool::new(thread_count);
|
let mut tpool = Pool::new(thread_count);
|
||||||
|
|
||||||
let image = Image::new(self.resolution.0, self.resolution.1);
|
let image = Image::new(self.resolution.0, self.resolution.1);
|
||||||
|
@ -174,12 +174,10 @@ impl Renderer {
|
||||||
print!("0.00%");
|
print!("0.00%");
|
||||||
let _ = io::stdout().flush();
|
let _ = io::stdout().flush();
|
||||||
|
|
||||||
// Determine bucket size based on a target number of samples
|
// Determine bucket size based on the per-thread maximum number of samples to
|
||||||
// per bucket.
|
// calculate at a time.
|
||||||
// TODO: make target samples per bucket configurable
|
|
||||||
let target_samples_per_bucket = 1usize << 12;
|
|
||||||
let (bucket_w, bucket_h) = {
|
let (bucket_w, bucket_h) = {
|
||||||
let target_pixels_per_bucket = target_samples_per_bucket as f64 / self.spp as f64;
|
let target_pixels_per_bucket = max_samples_per_bucket as f64 / self.spp as f64;
|
||||||
let target_bucket_dim = if target_pixels_per_bucket.sqrt() < 1.0 {
|
let target_bucket_dim = if target_pixels_per_bucket.sqrt() < 1.0 {
|
||||||
1usize
|
1usize
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user