diff options
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/addon/__init__.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 46 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 138 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 92 | ||||
-rw-r--r-- | intern/cycles/blender/blender_curves.cpp | 18 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 52 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 28 | ||||
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 290 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.h | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 137 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 9 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 13 |
14 files changed, 612 insertions, 249 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index eb792af7264..a2d6262fb20 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -102,6 +102,9 @@ class CyclesRender(bpy.types.RenderEngine): else: self.report({'ERROR'}, "OSL support disabled in this build.") + def update_render_passes(self, scene, srl): + engine.register_passes(self, scene, srl) + def engine_exit(): engine.exit() diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index ab57dd44bdb..3018fd5b316 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -205,3 +205,49 @@ def with_network(): def system_info(): import _cycles return _cycles.system_info() + +def register_passes(engine, scene, srl): + engine.register_pass(scene, srl, "Combined", 4, "RGBA", 'COLOR') + + if srl.use_pass_z: engine.register_pass(scene, srl, "Depth", 1, "Z", 'VALUE') + if srl.use_pass_mist: engine.register_pass(scene, srl, "Mist", 1, "Z", 'VALUE') + if srl.use_pass_normal: engine.register_pass(scene, srl, "Normal", 3, "XYZ", 'VECTOR') + if srl.use_pass_vector: engine.register_pass(scene, srl, "Vector", 4, "XYZW", 'VECTOR') + if srl.use_pass_uv: engine.register_pass(scene, srl, "UV", 3, "UVA", 'VECTOR') + if srl.use_pass_object_index: engine.register_pass(scene, srl, "IndexOB", 1, "X", 'VALUE') + if srl.use_pass_material_index: engine.register_pass(scene, srl, "IndexMA", 1, "X", 'VALUE') + if srl.use_pass_shadow: engine.register_pass(scene, srl, "Shadow", 3, "RGB", 'COLOR') + if srl.use_pass_ambient_occlusion: engine.register_pass(scene, srl, "AO", 3, "RGB", 'COLOR') + if srl.use_pass_diffuse_direct: engine.register_pass(scene, srl, "DiffDir", 3, "RGB", 'COLOR') + if srl.use_pass_diffuse_indirect: engine.register_pass(scene, srl, "DiffInd", 3, "RGB", 'COLOR') + if srl.use_pass_diffuse_color: engine.register_pass(scene, srl, "DiffCol", 3, "RGB", 'COLOR') + if srl.use_pass_glossy_direct: engine.register_pass(scene, srl, "GlossDir", 3, "RGB", 'COLOR') + if srl.use_pass_glossy_indirect: engine.register_pass(scene, srl, "GlossInd", 3, "RGB", 'COLOR') + if srl.use_pass_glossy_color: engine.register_pass(scene, srl, "GlossCol", 3, "RGB", 'COLOR') + if srl.use_pass_transmission_direct: engine.register_pass(scene, srl, "TransDir", 3, "RGB", 'COLOR') + if srl.use_pass_transmission_indirect: engine.register_pass(scene, srl, "TransInd", 3, "RGB", 'COLOR') + if srl.use_pass_transmission_color: engine.register_pass(scene, srl, "TransCol", 3, "RGB", 'COLOR') + if srl.use_pass_subsurface_direct: engine.register_pass(scene, srl, "SubsurfaceDir", 3, "RGB", 'COLOR') + if srl.use_pass_subsurface_indirect: engine.register_pass(scene, srl, "SubsurfaceInd", 3, "RGB", 'COLOR') + if srl.use_pass_subsurface_color: engine.register_pass(scene, srl, "SubsurfaceCol", 3, "RGB", 'COLOR') + if srl.use_pass_emit: engine.register_pass(scene, srl, "Emit", 3, "RGB", 'COLOR') + if srl.use_pass_environment: engine.register_pass(scene, srl, "Env", 3, "RGB", 'COLOR') + + crl = srl.cycles + if crl.pass_debug_bvh_traversed_nodes: engine.register_pass(scene, srl, "Debug BVH Traversed Nodes", 1, "X", 'VALUE') + if crl.pass_debug_bvh_traversed_instances: engine.register_pass(scene, srl, "Debug BVH Traversed Instances", 1, "X", 'VALUE') + if crl.pass_debug_bvh_intersections: engine.register_pass(scene, srl, "Debug BVH Intersections", 1, "X", 'VALUE') + if crl.pass_debug_ray_bounces: engine.register_pass(scene, srl, "Debug Ray Bounces", 1, "X", 'VALUE') + + cscene = scene.cycles + if crl.use_denoising and crl.denoising_store_passes and not cscene.use_progressive_refine: + engine.register_pass(scene, srl, "Denoising Normal", 3, "XYZ", 'VECTOR') + engine.register_pass(scene, srl, "Denoising Normal Variance", 3, "XYZ", 'VECTOR') + engine.register_pass(scene, srl, "Denoising Albedo", 3, "RGB", 'COLOR') + engine.register_pass(scene, srl, "Denoising Albedo Variance", 3, "RGB", 'COLOR') + engine.register_pass(scene, srl, "Denoising Depth", 1, "Z", 'VALUE') + engine.register_pass(scene, srl, "Denoising Depth Variance", 1, "Z", 'VALUE') + engine.register_pass(scene, srl, "Denoising Shadow A", 3, "XYV", 'VECTOR') + engine.register_pass(scene, srl, "Denoising Shadow B", 3, "XYV", 'VECTOR') + engine.register_pass(scene, srl, "Denoising Image", 3, "RGB", 'COLOR') + engine.register_pass(scene, srl, "Denoising Image Variance", 3, "RGB", 'COLOR') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index cbf469b3a89..68474529ed3 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -695,10 +695,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): update=devices_update_callback ) - cls.debug_opencl_kernel_single_program = BoolProperty(name="Single Program", default=False, update=devices_update_callback); + cls.debug_opencl_kernel_single_program = BoolProperty( + name="Single Program", + default=True, + update=devices_update_callback, + ) cls.debug_use_opencl_debug = BoolProperty(name="Debug OpenCL", default=False) + cls.debug_opencl_mem_limit = IntProperty(name="Memory limit", default=0, + description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)") + @classmethod def unregister(cls): del bpy.types.Scene.cycles @@ -1166,6 +1173,125 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): def unregister(cls): del bpy.types.Scene.cycles_curves +def update_render_passes(self, context): + scene = context.scene + rd = scene.render + rl = rd.layers.active + rl.update_render_passes() + +class CyclesRenderLayerSettings(bpy.types.PropertyGroup): + @classmethod + def register(cls): + bpy.types.SceneRenderLayer.cycles = PointerProperty( + name="Cycles SceneRenderLayer Settings", + description="Cycles SceneRenderLayer Settings", + type=cls, + ) + cls.pass_debug_bvh_traversed_nodes = BoolProperty( + name="Debug BVH Traversed Nodes", + description="Store Debug BVH Traversed Nodes pass", + default=False, + update=update_render_passes, + ) + cls.pass_debug_bvh_traversed_instances = BoolProperty( + name="Debug BVH Traversed Instances", + description="Store Debug BVH Traversed Instances pass", + default=False, + update=update_render_passes, + ) + cls.pass_debug_bvh_intersections = BoolProperty( + name="Debug BVH Intersections", + description="Store Debug BVH Intersections", + default=False, + update=update_render_passes, + ) + cls.pass_debug_ray_bounces = BoolProperty( + name="Debug Ray Bounces", + description="Store Debug Ray Bounces pass", + default=False, + update=update_render_passes, + ) + + cls.use_denoising = BoolProperty( + name="Use Denoising", + description="Denoise the rendered image", + default=False, + update=update_render_passes, + ) + cls.denoising_diffuse_direct = BoolProperty( + name="Diffuse Direct", + description="Denoise the direct diffuse lighting", + default=True, + ) + cls.denoising_diffuse_indirect = BoolProperty( + name="Diffuse Indirect", + description="Denoise the indirect diffuse lighting", + default=True, + ) + cls.denoising_glossy_direct = BoolProperty( + name="Glossy Direct", + description="Denoise the direct glossy lighting", + default=True, + ) + cls.denoising_glossy_indirect = BoolProperty( + name="Glossy Indirect", + description="Denoise the indirect glossy lighting", + default=True, + ) + cls.denoising_transmission_direct = BoolProperty( + name="Transmission Direct", + description="Denoise the direct transmission lighting", + default=True, + ) + cls.denoising_transmission_indirect = BoolProperty( + name="Transmission Indirect", + description="Denoise the indirect transmission lighting", + default=True, + ) + cls.denoising_subsurface_direct = BoolProperty( + name="Subsurface Direct", + description="Denoise the direct subsurface lighting", + default=True, + ) + cls.denoising_subsurface_indirect = BoolProperty( + name="Subsurface Indirect", + description="Denoise the indirect subsurface lighting", + default=True, + ) + cls.denoising_strength = FloatProperty( + name="Denoising Strength", + description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)", + min=0.0, max=1.0, + default=0.5, + ) + cls.denoising_feature_strength = FloatProperty( + name="Denoising Feature Strength", + description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)", + min=0.0, max=1.0, + default=0.5, + ) + cls.denoising_radius = IntProperty( + name="Denoising Radius", + description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)", + min=1, max=25, + default=8, + ) + cls.denoising_relative_pca = BoolProperty( + name="Relative filter", + description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)", + default=False, + ) + cls.denoising_store_passes = BoolProperty( + name="Store denoising passes", + description="Store the denoising feature passes and the noisy image", + default=False, + update=update_render_passes, + ) + + @classmethod + def unregister(cls): + del bpy.types.SceneRenderLayer.cycles + class CyclesCurveSettings(bpy.types.PropertyGroup): @classmethod @@ -1297,14 +1423,14 @@ class CyclesPreferences(bpy.types.AddonPreferences): row = layout.row() if self.compute_device_type == 'CUDA' and cuda_devices: - col = row.column(align=True) + box = row.box() for device in cuda_devices: - col.prop(device, "use", text=device.name, toggle=True) + box.prop(device, "use", text=device.name) if self.compute_device_type == 'OPENCL' and opencl_devices: - col = row.column(align=True) + box = row.box() for device in opencl_devices: - col.prop(device, "use", text=device.name, toggle=True) + box.prop(device, "use", text=device.name) def draw(self, context): @@ -1324,6 +1450,7 @@ def register(): bpy.utils.register_class(CyclesCurveSettings) bpy.utils.register_class(CyclesDeviceSettings) bpy.utils.register_class(CyclesPreferences) + bpy.utils.register_class(CyclesRenderLayerSettings) def unregister(): @@ -1339,3 +1466,4 @@ def unregister(): bpy.utils.unregister_class(CyclesCurveSettings) bpy.utils.unregister_class(CyclesDeviceSettings) bpy.utils.unregister_class(CyclesPreferences) + bpy.utils.unregister_class(CyclesRenderLayerSettings) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 2b50d272be8..49beebe5ab4 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -78,7 +78,7 @@ def use_cuda(context): def use_branched_path(context): cscene = context.scene.cycles - return (cscene.progressive == 'BRANCHED_PATH' and not use_opencl(context)) + return (cscene.progressive == 'BRANCHED_PATH') def use_sample_all_lights(context): @@ -156,7 +156,6 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): row = layout.row() sub = row.row() - sub.active = get_device_type(context) != 'OPENCL' or use_cpu(context) sub.prop(cscene, "progressive", text="") row.prop(cscene, "use_square_samples") @@ -204,8 +203,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): col.prop(cscene, "sample_all_lights_direct") col.prop(cscene, "sample_all_lights_indirect") - if not (use_opencl(context) and cscene.feature_set != 'EXPERIMENTAL'): - layout.row().prop(cscene, "sampling_pattern", text="Pattern") + layout.row().prop(cscene, "sampling_pattern", text="Pattern") for rl in scene.render.layers: if rl.samples > 0: @@ -478,11 +476,14 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} def draw(self, context): + import _cycles + layout = self.layout scene = context.scene rd = scene.render rl = rd.layers.active + crl = rl.cycles split = layout.split() @@ -529,8 +530,18 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): col.prop(rl, "use_pass_emit", text="Emission") col.prop(rl, "use_pass_environment") - if hasattr(rd, "debug_pass_type"): - layout.prop(rd, "debug_pass_type") + if context.scene.cycles.feature_set == 'EXPERIMENTAL': + col.separator() + sub = col.column() + sub.active = crl.use_denoising + sub.prop(crl, "denoising_store_passes", text="Denoising") + + if _cycles.with_cycles_debug: + col = layout.column() + col.prop(crl, "pass_debug_bvh_traversed_nodes") + col.prop(crl, "pass_debug_bvh_traversed_instances") + col.prop(crl, "pass_debug_bvh_intersections") + col.prop(crl, "pass_debug_ray_bounces") class CyclesRender_PT_views(CyclesButtonsPanel, Panel): @@ -576,6 +587,71 @@ class CyclesRender_PT_views(CyclesButtonsPanel, Panel): row.prop(rv, "camera_suffix", text="") +class CyclesRender_PT_denoising(CyclesButtonsPanel, Panel): + bl_label = "Denoising" + bl_context = "render_layer" + bl_options = {'DEFAULT_CLOSED'} + + def draw_header(self, context): + rd = context.scene.render + rl = rd.layers.active + crl = rl.cycles + cscene = context.scene.cycles + layout = self.layout + + layout.active = not cscene.use_progressive_refine + layout.prop(crl, "use_denoising", text="") + + def draw(self, context): + layout = self.layout + + scene = context.scene + cscene = scene.cycles + rd = scene.render + rl = rd.layers.active + crl = rl.cycles + + layout.active = crl.use_denoising and not cscene.use_progressive_refine + + split = layout.split() + + col = split.column() + sub = col.column(align=True) + sub.prop(crl, "denoising_radius", text="Radius") + sub.prop(crl, "denoising_strength", slider=True, text="Strength") + + col = split.column() + sub = col.column(align=True) + sub.prop(crl, "denoising_feature_strength", slider=True, text="Feature Strength") + sub.prop(crl, "denoising_relative_pca") + + layout.separator() + + row = layout.row() + row.label(text="Diffuse:") + sub = row.row(align=True) + sub.prop(crl, "denoising_diffuse_direct", text="Direct", toggle=True) + sub.prop(crl, "denoising_diffuse_indirect", text="Indirect", toggle=True) + + row = layout.row() + row.label(text="Glossy:") + sub = row.row(align=True) + sub.prop(crl, "denoising_glossy_direct", text="Direct", toggle=True) + sub.prop(crl, "denoising_glossy_indirect", text="Indirect", toggle=True) + + row = layout.row() + row.label(text="Transmission:") + sub = row.row(align=True) + sub.prop(crl, "denoising_transmission_direct", text="Direct", toggle=True) + sub.prop(crl, "denoising_transmission_indirect", text="Indirect", toggle=True) + + row = layout.row() + row.label(text="Subsurface:") + sub = row.row(align=True) + sub.prop(crl, "denoising_subsurface_direct", text="Direct", toggle=True) + sub.prop(crl, "denoising_subsurface_indirect", text="Indirect", toggle=True) + + class Cycles_PT_post_processing(CyclesButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} @@ -1532,6 +1608,7 @@ class CyclesRender_PT_debug(CyclesButtonsPanel, Panel): col.prop(cscene, "debug_opencl_device_type", text="Device") col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program") col.prop(cscene, "debug_use_opencl_debug", text="Debug") + col.prop(cscene, "debug_opencl_mem_limit") class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel): @@ -1634,7 +1711,7 @@ def draw_device(self, context): layout.prop(cscene, "feature_set") - split = layout.split(percentage=1/3) + split = layout.split(percentage=1 / 3) split.label("Device:") row = split.row() row.active = show_device_active(context) @@ -1729,6 +1806,7 @@ classes = ( CyclesRender_PT_layer_options, CyclesRender_PT_layer_passes, CyclesRender_PT_views, + CyclesRender_PT_denoising, Cycles_PT_post_processing, CyclesCamera_PT_dof, Cycles_PT_context_material, diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 6fa038e8bf0..42b985305ea 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -411,7 +411,7 @@ static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, } } - mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size()); + mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); @@ -546,7 +546,7 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, } } - mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size()); + mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); @@ -776,17 +776,17 @@ static void ExportCurveTriangleVcol(ParticleCurveData *CData, for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { for(int section = 0; section < resol; section++) { - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve])); vertexindex++; } } @@ -1004,7 +1004,7 @@ void BlenderSync::sync_curves(Mesh *mesh, for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++) if(!(CData.curve_keynum[curve] <= 1 || CData.curve_length[curve] == 0.0f)) - fdata[i++] = color_srgb_to_scene_linear(CData.curve_vcol[curve]); + fdata[i++] = color_srgb_to_scene_linear_v3(CData.curve_vcol[curve]); } } } diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 54571b1fea1..b4cca5f00f4 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -51,8 +50,7 @@ enum { * Two triangles has vertex indices in the original Blender-side face. * If face is already a quad tri_b will not be initialized. */ -inline void face_split_tri_indices(const int num_verts, - const int face_flag, +inline void face_split_tri_indices(const int face_flag, int tri_a[3], int tri_b[3]) { @@ -60,21 +58,19 @@ inline void face_split_tri_indices(const int num_verts, tri_a[0] = 0; tri_a[1] = 1; tri_a[2] = 3; - if(num_verts == 4) { - tri_b[0] = 2; - tri_b[1] = 3; - tri_b[2] = 1; - } + + tri_b[0] = 2; + tri_b[1] = 3; + tri_b[2] = 1; } else /*if(face_flag & FACE_FLAG_DIVIDE_13)*/ { tri_a[0] = 0; tri_a[1] = 1; tri_a[2] = 2; - if(num_verts == 4) { - tri_b[0] = 0; - tri_b[1] = 2; - tri_b[2] = 3; - } + + tri_b[0] = 0; + tri_b[1] = 2; + tri_b[2] = 3; } } @@ -251,7 +247,7 @@ static void mikk_compute_tangents(BL::Mesh& b_mesh, for(int i = 0; i < nverts.size(); i++) { int tri_a[3], tri_b[3]; - face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); + face_split_tri_indices(face_flags[i], tri_a, tri_b); tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_a[0]]); tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_a[1]]); @@ -293,7 +289,7 @@ static void create_mesh_volume_attribute(BL::Object& b_ob, if(!b_domain) return; - + Attribute *attr = mesh->attributes.add(std); VoxelAttribute *volume_data = attr->data_voxel(); bool is_float, is_linear; @@ -356,7 +352,7 @@ static void attr_create_vertex_color(Scene *scene, int n = p->loop_total(); for(int i = 0; i < n; i++) { float3 color = get_float3(l->data[p->loop_start() + i].color()); - *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear(color)); + *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear_v3(color)); } } } @@ -377,14 +373,14 @@ static void attr_create_vertex_color(Scene *scene, for(l->data.begin(c); c != l->data.end(); ++c, ++i) { int tri_a[3], tri_b[3]; - face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); + face_split_tri_indices(face_flags[i], tri_a, tri_b); uchar4 colors[4]; - colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1()))); - colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2()))); - colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3()))); + colors[0] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color1()))); + colors[1] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color2()))); + colors[2] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color3()))); if(nverts[i] == 4) { - colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4()))); + colors[3] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color4()))); } cdata[0] = colors[tri_a[0]]; @@ -470,7 +466,7 @@ static void attr_create_uv_map(Scene *scene, for(l->data.begin(t); t != l->data.end(); ++t, ++i) { int tri_a[3], tri_b[3]; - face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); + face_split_tri_indices(face_flags[i], tri_a, tri_b); float3 uvs[4]; uvs[0] = get_float3(t->uv1()); @@ -982,7 +978,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, else used_shaders.push_back(scene->default_surface); } - + /* test if we need to sync */ int requested_geometry_flags = Mesh::GEOMETRY_NONE; if(render_layer.use_surfaces) { @@ -1017,12 +1013,12 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, /* ensure we only sync instanced meshes once */ if(mesh_synced.find(mesh) != mesh_synced.end()) return mesh; - + mesh_synced.insert(mesh); /* create derived mesh */ array<int> oldtriangle = mesh->triangles; - + /* compares curve_keys rather than strands in order to handle quick hair * adjustments in dynamic BVH - other methods could probably do this better*/ array<float3> oldcurve_keys = mesh->curve_keys; @@ -1111,7 +1107,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0) rebuild = true; } - + mesh->tag_update(scene, rebuild); return mesh; @@ -1140,7 +1136,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, if(scene->need_motion() == Scene::MOTION_BLUR) { if(!mesh->use_motion_blur) return; - + /* see if this mesh needs motion data at this time */ vector<float> object_times = object->motion_times(); bool found = false; @@ -1172,7 +1168,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, if(!numverts && !numkeys) return; - + /* skip objects without deforming modifiers. this is not totally reliable, * would need a more extensive check to see which objects are animated */ BL::Mesh b_mesh(PointerRNA_NULL); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index d05699236cc..a930c439370 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -379,27 +379,16 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, } } - /* random number */ - object->random_id = hash_string(object->name.c_str()); - - if(persistent_id) { - for(int i = 0; i < OBJECT_PERSISTENT_ID_SIZE; i++) - object->random_id = hash_int_2d(object->random_id, persistent_id[i]); - } - else - object->random_id = hash_int_2d(object->random_id, 0); - - if(b_parent.ptr.data != b_ob.ptr.data) - object->random_id ^= hash_int(hash_string(b_parent.name().c_str())); - - /* dupli texture coordinates */ + /* dupli texture coordinates and random_id */ if(b_dupli_ob) { object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f); object->dupli_uv = get_float2(b_dupli_ob.uv()); + object->random_id = b_dupli_ob.random_id(); } else { object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f); object->dupli_uv = make_float2(0.0f, 0.0f); + object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0); } object->tag_update(scene); @@ -489,7 +478,7 @@ static bool object_render_hide_duplis(BL::Object& b_ob) /* Object Loop */ -void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) +void BlenderSync::sync_objects(float motion_time) { /* layer data */ uint scene_layer = render_layer.scene_layer; @@ -517,7 +506,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) * 1 : DAG_EVAL_PREVIEW * 2 : DAG_EVAL_RENDER */ - int dupli_settings = preview ? 1 : 2; + int dupli_settings = (render_layer.use_viewport_visibility) ? 1 : 2; bool cancel = false; bool use_portal = false; @@ -552,7 +541,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) { Transform tfm = get_transform(b_dup->matrix()); BL::Object b_dup_ob = b_dup->object(); - bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); + bool dup_hide = (render_layer.use_viewport_visibility)? b_dup_ob.hide(): b_dup_ob.hide_render(); bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP); bool hide_tris; @@ -628,7 +617,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) } void BlenderSync::sync_motion(BL::RenderSettings& b_render, - BL::SpaceView3D& b_v3d, BL::Object& b_override, int width, int height, void **python_thread_state) @@ -665,7 +653,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render, b_engine.frame_set(frame, subframe); python_thread_state_save(python_thread_state); sync_camera_motion(b_render, b_cam, width, height, 0.0f); - sync_objects(b_v3d, 0.0f); + sync_objects(0.0f); } /* always sample these times for camera motion */ @@ -699,7 +687,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render, } /* sync object */ - sync_objects(b_v3d, relative_time); + sync_objects(relative_time); } /* we need to set the python thread state again because this diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index d509e9de981..54973fd1b7f 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -106,6 +106,7 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene) } /* Synchronize other OpenCL flags. */ flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug"); + flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit"))*1024*1024; flags.opencl.single_program = get_boolean(cscene, "debug_opencl_kernel_single_program"); return flags.opencl.device_type != opencl_device_type || flags.opencl.kernel_type != opencl_kernel_type; @@ -811,6 +812,14 @@ void *CCL_python_module_init() PyModule_AddStringConstant(mod, "osl_version_string", "unknown"); #endif +#ifdef WITH_CYCLES_DEBUG + PyModule_AddObject(mod, "with_cycles_debug", Py_True); + Py_INCREF(Py_True); +#else + PyModule_AddObject(mod, "with_cycles_debug", Py_False); + Py_INCREF(Py_False); +#endif + #ifdef WITH_NETWORK PyModule_AddObject(mod, "with_network", Py_True); Py_INCREF(Py_True); diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 26f9bccd95d..12de3da063f 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -129,9 +129,9 @@ void BlenderSession::create_session() scene = new Scene(scene_params, session_params.device); /* setup callbacks for builtin image support */ - scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7); - scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4); - scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4); + scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7, _8); + scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5); + scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5); /* create session */ session = new Session(session_params); @@ -243,90 +243,6 @@ void BlenderSession::free_session() delete session; } -static PassType get_pass_type(BL::RenderPass& b_pass) -{ - switch(b_pass.type()) { - case BL::RenderPass::type_COMBINED: - return PASS_COMBINED; - - case BL::RenderPass::type_Z: - return PASS_DEPTH; - case BL::RenderPass::type_MIST: - return PASS_MIST; - case BL::RenderPass::type_NORMAL: - return PASS_NORMAL; - case BL::RenderPass::type_OBJECT_INDEX: - return PASS_OBJECT_ID; - case BL::RenderPass::type_UV: - return PASS_UV; - case BL::RenderPass::type_VECTOR: - return PASS_MOTION; - case BL::RenderPass::type_MATERIAL_INDEX: - return PASS_MATERIAL_ID; - - case BL::RenderPass::type_DIFFUSE_DIRECT: - return PASS_DIFFUSE_DIRECT; - case BL::RenderPass::type_GLOSSY_DIRECT: - return PASS_GLOSSY_DIRECT; - case BL::RenderPass::type_TRANSMISSION_DIRECT: - return PASS_TRANSMISSION_DIRECT; - case BL::RenderPass::type_SUBSURFACE_DIRECT: - return PASS_SUBSURFACE_DIRECT; - - case BL::RenderPass::type_DIFFUSE_INDIRECT: - return PASS_DIFFUSE_INDIRECT; - case BL::RenderPass::type_GLOSSY_INDIRECT: - return PASS_GLOSSY_INDIRECT; - case BL::RenderPass::type_TRANSMISSION_INDIRECT: - return PASS_TRANSMISSION_INDIRECT; - case BL::RenderPass::type_SUBSURFACE_INDIRECT: - return PASS_SUBSURFACE_INDIRECT; - - case BL::RenderPass::type_DIFFUSE_COLOR: - return PASS_DIFFUSE_COLOR; - case BL::RenderPass::type_GLOSSY_COLOR: - return PASS_GLOSSY_COLOR; - case BL::RenderPass::type_TRANSMISSION_COLOR: - return PASS_TRANSMISSION_COLOR; - case BL::RenderPass::type_SUBSURFACE_COLOR: - return PASS_SUBSURFACE_COLOR; - - case BL::RenderPass::type_EMIT: - return PASS_EMISSION; - case BL::RenderPass::type_ENVIRONMENT: - return PASS_BACKGROUND; - case BL::RenderPass::type_AO: - return PASS_AO; - case BL::RenderPass::type_SHADOW: - return PASS_SHADOW; - - case BL::RenderPass::type_DIFFUSE: - case BL::RenderPass::type_COLOR: - case BL::RenderPass::type_REFRACTION: - case BL::RenderPass::type_SPECULAR: - case BL::RenderPass::type_REFLECTION: - return PASS_NONE; -#ifdef WITH_CYCLES_DEBUG - case BL::RenderPass::type_DEBUG: - { - switch(b_pass.debug_type()) { - case BL::RenderPass::debug_type_BVH_TRAVERSED_NODES: - return PASS_BVH_TRAVERSED_NODES; - case BL::RenderPass::debug_type_BVH_TRAVERSED_INSTANCES: - return PASS_BVH_TRAVERSED_INSTANCES; - case BL::RenderPass::debug_type_BVH_INTERSECTIONS: - return PASS_BVH_INTERSECTIONS; - case BL::RenderPass::debug_type_RAY_BOUNCES: - return PASS_RAY_BOUNCES; - } - break; - } -#endif - } - - return PASS_NONE; -} - static ShaderEvalType get_shader_type(const string& pass_type) { const char *shader_type = pass_type.c_str(); @@ -383,12 +299,13 @@ static BL::RenderResult begin_render_result(BL::RenderEngine& b_engine, static void end_render_result(BL::RenderEngine& b_engine, BL::RenderResult& b_rr, bool cancel, + bool highlight, bool do_merge_results) { - b_engine.end_result(b_rr, (int)cancel, (int)do_merge_results); + b_engine.end_result(b_rr, (int)cancel, (int) highlight, (int)do_merge_results); } -void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only) +void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight) { BufferParams& params = rtile.buffers->params; int x = params.full_x - session->tile_manager.params.full_x; @@ -424,37 +341,37 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda update_render_result(b_rr, b_rlay, rtile); } - end_render_result(b_engine, b_rr, true, true); + end_render_result(b_engine, b_rr, true, highlight, true); } else { /* write result */ write_render_result(b_rr, b_rlay, rtile); - end_render_result(b_engine, b_rr, false, true); + end_render_result(b_engine, b_rr, false, false, true); } } void BlenderSession::write_render_tile(RenderTile& rtile) { - do_write_update_render_tile(rtile, false); + do_write_update_render_tile(rtile, false, false); } -void BlenderSession::update_render_tile(RenderTile& rtile) +void BlenderSession::update_render_tile(RenderTile& rtile, bool highlight) { /* use final write for preview renders, otherwise render result wouldn't be * be updated in blender side * would need to be investigated a bit further, but for now shall be fine */ if(!b_engine.is_preview()) - do_write_update_render_tile(rtile, true); + do_write_update_render_tile(rtile, true, highlight); else - do_write_update_render_tile(rtile, false); + do_write_update_render_tile(rtile, false, false); } void BlenderSession::render() { /* set callback to write out render results */ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1); - session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1); + session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2); /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); @@ -475,33 +392,38 @@ void BlenderSession::render() /* layer will be missing if it was disabled in the UI */ if(b_single_rlay == b_rr.layers.end()) { - end_render_result(b_engine, b_rr, true, false); + end_render_result(b_engine, b_rr, true, true, false); continue; } BL::RenderLayer b_rlay = *b_single_rlay; /* add passes */ - array<Pass> passes; - Pass::add(PASS_COMBINED, passes); - - if(session_params.device.advanced_shading) { - - /* loop over passes */ - BL::RenderLayer::passes_iterator b_pass_iter; - - for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) { - BL::RenderPass b_pass(*b_pass_iter); - PassType pass_type = get_pass_type(b_pass); + array<Pass> passes = sync->sync_render_passes(b_rlay, *b_layer_iter, session_params); + buffer_params.passes = passes; - if(pass_type == PASS_MOTION && scene->integrator->motion_blur) - continue; - if(pass_type != PASS_NONE) - Pass::add(pass_type, passes); - } - } + PointerRNA crl = RNA_pointer_get(&b_layer_iter->ptr, "cycles"); + bool use_denoising = !session_params.progressive_refine && get_boolean(crl, "use_denoising"); + buffer_params.denoising_data_pass = use_denoising; + session->tile_manager.schedule_denoising = use_denoising; + session->params.use_denoising = use_denoising; + scene->film->denoising_data_pass = buffer_params.denoising_data_pass; + scene->film->denoising_flags = 0; + if(!get_boolean(crl, "denoising_diffuse_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_DIR; + if(!get_boolean(crl, "denoising_diffuse_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_IND; + if(!get_boolean(crl, "denoising_glossy_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_DIR; + if(!get_boolean(crl, "denoising_glossy_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_IND; + if(!get_boolean(crl, "denoising_transmission_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_DIR; + if(!get_boolean(crl, "denoising_transmission_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_IND; + if(!get_boolean(crl, "denoising_subsurface_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_DIR; + if(!get_boolean(crl, "denoising_subsurface_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_IND; + scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES); + buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass; + session->params.denoising_radius = get_int(crl, "denoising_radius"); + session->params.denoising_strength = get_float(crl, "denoising_strength"); + session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength"); + session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca"); - buffer_params.passes = passes; scene->film->pass_alpha_threshold = b_layer_iter->pass_alpha_threshold(); scene->film->tag_passes_update(scene, passes); scene->film->tag_update(scene); @@ -555,7 +477,7 @@ void BlenderSession::render() } /* free result without merging */ - end_render_result(b_engine, b_rr, true, false); + end_render_result(b_engine, b_rr, true, true, false); if(session->progress.get_cancel()) break; @@ -636,8 +558,6 @@ void BlenderSession::bake(BL::Object& b_object, float result[]) { ShaderEvalType shader_type = get_shader_type(pass_type); - size_t object_index = OBJECT_NONE; - int tri_offset = 0; /* Set baking flag in advance, so kernel loading can check if we need * any baking capabilities. @@ -647,9 +567,6 @@ void BlenderSession::bake(BL::Object& b_object, /* ensure kernels are loaded before we do any scene updates */ session->load_kernels(); - if(session->progress.get_cancel()) - return; - if(shader_type == SHADER_EVAL_UV) { /* force UV to be available */ Pass::add(PASS_UV, scene->film->passes); @@ -667,50 +584,61 @@ void BlenderSession::bake(BL::Object& b_object, scene->film->tag_update(scene); scene->integrator->tag_update(scene); - /* update scene */ - BL::Object b_camera_override(b_engine.camera_override()); - sync->sync_camera(b_render, b_camera_override, width, height, ""); - sync->sync_data(b_render, - b_v3d, - b_camera_override, - width, height, - &python_thread_state, - b_rlay_name.c_str()); + if(!session->progress.get_cancel()) { + /* update scene */ + BL::Object b_camera_override(b_engine.camera_override()); + sync->sync_camera(b_render, b_camera_override, width, height, ""); + sync->sync_data(b_render, + b_v3d, + b_camera_override, + width, height, + &python_thread_state, + b_rlay_name.c_str()); + } - /* get buffer parameters */ - SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height); + BakeData *bake_data = NULL; + + if(!session->progress.get_cancel()) { + /* get buffer parameters */ + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height); - scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); + scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); - /* set number of samples */ - session->tile_manager.set_samples(session_params.samples); - session->reset(buffer_params, session_params.samples); - session->update_scene(); + /* set number of samples */ + session->tile_manager.set_samples(session_params.samples); + session->reset(buffer_params, session_params.samples); + session->update_scene(); - /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ - for(size_t i = 0; i < scene->objects.size(); i++) { - if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) { - object_index = i; - tri_offset = scene->objects[i]->mesh->tri_offset; - break; - } - } + /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ + size_t object_index = OBJECT_NONE; + int tri_offset = 0; - int object = object_index; + for(size_t i = 0; i < scene->objects.size(); i++) { + if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) { + object_index = i; + tri_offset = scene->objects[i]->mesh->tri_offset; + break; + } + } - BakeData *bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); + int object = object_index; - populate_bake_data(bake_data, object_id, pixel_array, num_pixels); + bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); + populate_bake_data(bake_data, object_id, pixel_array, num_pixels); - /* set number of samples */ - session->tile_manager.set_samples(session_params.samples); - session->reset(buffer_params, session_params.samples); - session->update_scene(); + /* set number of samples */ + session->tile_manager.set_samples(session_params.samples); + session->reset(buffer_params, session_params.samples); + session->update_scene(); - session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this)); + session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this)); + } - scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_pass_filter, bake_data, result); + /* Perform bake. Check cancel to avoid crash with incomplete scene data. */ + if(!session->progress.get_cancel()) { + scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_pass_filter, bake_data, result); + } /* free all memory used (host and device), so we wouldn't leave render * engine with extra memory allocated @@ -753,19 +681,31 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult& b_rr, BL::RenderPass b_pass(*b_iter); /* find matching pass type */ - PassType pass_type = get_pass_type(b_pass); + PassType pass_type = BlenderSync::get_pass_type(b_pass); int components = b_pass.channels(); - /* copy pixels */ - if(!buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0])) + bool read = false; + if(pass_type != PASS_NONE) { + /* copy pixels */ + read = buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0]); + } + else { + int denoising_offset = BlenderSync::get_denoising_pass(b_pass); + if(denoising_offset >= 0) { + read = buffers->get_denoising_pass_rect(denoising_offset, exposure, sample, components, &pixels[0]); + } + } + + if(!read) { memset(&pixels[0], 0, pixels.size()*sizeof(float)); + } b_pass.rect(&pixels[0]); } } else { /* copy combined pass */ - BL::RenderPass b_combined_pass(b_rlay.passes.find_by_type(BL::RenderPass::type_COMBINED, b_rview_name.c_str())); + BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str())); if(buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0])) b_combined_pass.rect(&pixels[0]); } @@ -1073,7 +1013,8 @@ void BlenderSession::builtin_image_info(const string &builtin_name, int &width, int &height, int &depth, - int &channels) + int &channels, + bool& free_cache) { /* empty image */ is_float = false; @@ -1081,6 +1022,7 @@ void BlenderSession::builtin_image_info(const string &builtin_name, height = 1; depth = 0; channels = 0; + free_cache = false; if(!builtin_data) return; @@ -1094,6 +1036,7 @@ void BlenderSession::builtin_image_info(const string &builtin_name, /* image data */ BL::Image b_image(b_id); + free_cache = !b_image.has_data(); is_float = b_image.is_float(); width = b_image.size()[0]; height = b_image.size()[1]; @@ -1154,7 +1097,8 @@ void BlenderSession::builtin_image_info(const string &builtin_name, bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels, - const size_t pixels_size) + const size_t pixels_size, + const bool free_cache) { if(!builtin_data) { return false; @@ -1175,7 +1119,6 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name, if(image_pixels && num_pixels * channels == pixels_size) { memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char)); - MEM_freeN(image_pixels); } else { if(channels == 1) { @@ -1194,6 +1137,16 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name, } } } + + if(image_pixels) { + MEM_freeN(image_pixels); + } + + /* Free image buffers to save memory during render. */ + if(free_cache) { + b_image.buffers_free(); + } + /* Premultiply, byte images are always straight for Blender. */ unsigned char *cp = pixels; for(size_t i = 0; i < num_pixels; i++, cp += channels) { @@ -1207,7 +1160,8 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name, bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels, - const size_t pixels_size) + const size_t pixels_size, + const bool free_cache) { if(!builtin_data) { return false; @@ -1232,7 +1186,6 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, if(image_pixels && num_pixels * channels == pixels_size) { memcpy(pixels, image_pixels, pixels_size * sizeof(float)); - MEM_freeN(image_pixels); } else { if(channels == 1) { @@ -1252,6 +1205,15 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, } } + if(image_pixels) { + MEM_freeN(image_pixels); + } + + /* Free image buffers to save memory during render. */ + if(free_cache) { + b_image.buffers_free(); + } + return true; } else if(b_id.is_a(&RNA_Object)) { diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 22b21a18f2e..cbd2303d282 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -79,7 +79,7 @@ public: void update_render_result(BL::RenderResult& b_rr, BL::RenderLayer& b_rlay, RenderTile& rtile); - void update_render_tile(RenderTile& rtile); + void update_render_tile(RenderTile& rtile, bool highlight); /* interactive updates */ void synchronize(); @@ -147,7 +147,7 @@ protected: BL::RenderLayer& b_rlay, RenderTile& rtile, bool do_update_only); - void do_write_update_render_tile(RenderTile& rtile, bool do_update_only); + void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight); int builtin_image_frame(const string &builtin_name); void builtin_image_info(const string &builtin_name, @@ -156,15 +156,18 @@ protected: int &width, int &height, int &depth, - int &channels); + int &channels, + bool &free_cache); bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels, - const size_t pixels_size); + const size_t pixels_size, + const bool free_cache); bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels, - const size_t pixels_size); + const size_t pixels_size, + const bool free_cache); /* Update tile manager to reflect resumable render settings. */ void update_resumable_tile_manager(int num_samples); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 3f04f11aab4..bdbab1006c0 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -521,6 +521,19 @@ static ShaderNode *add_node(Scene *scene, } node = hair; } + else if(b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) { + BL::ShaderNodeBsdfPrincipled b_principled_node(b_node); + PrincipledBsdfNode *principled = new PrincipledBsdfNode(); + switch (b_principled_node.distribution()) { + case BL::ShaderNodeBsdfPrincipled::distribution_GGX: + principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + break; + case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX: + principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; + break; + } + node = principled; + } else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) { node = new TranslucentBsdfNode(); } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3b071bf0e7d..3a00384458a 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -210,10 +210,9 @@ void BlenderSync::sync_data(BL::RenderSettings& b_render, scene->need_motion() == Scene::MOTION_NONE || scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) { - sync_objects(b_v3d); + sync_objects(); } sync_motion(b_render, - b_v3d, b_override, width, height, python_thread_state); @@ -330,6 +329,9 @@ void BlenderSync::sync_integrator() integrator->ao_bounces = get_int(cscene, "ao_bounces_render"); } } + else { + integrator->ao_bounces = 0; + } if(integrator->modified(previntegrator)) integrator->tag_update(scene); @@ -480,6 +482,137 @@ void BlenderSync::sync_images() } } +/* Passes */ +PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass) +{ + string name = b_pass.name(); +#define MAP_PASS(passname, passtype) if(name == passname) return passtype; + /* NOTE: Keep in sync with defined names from DNA_scene_types.h */ + MAP_PASS("Combined", PASS_COMBINED); + MAP_PASS("Depth", PASS_DEPTH); + MAP_PASS("Mist", PASS_MIST); + MAP_PASS("Normal", PASS_NORMAL); + MAP_PASS("IndexOB", PASS_OBJECT_ID); + MAP_PASS("UV", PASS_UV); + MAP_PASS("Vector", PASS_MOTION); + MAP_PASS("IndexMA", PASS_MATERIAL_ID); + + MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT); + MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT); + MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT); + MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT); + + MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT); + MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT); + MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT); + MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT); + + MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR); + MAP_PASS("GlossCol", PASS_GLOSSY_COLOR); + MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR); + MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR); + + MAP_PASS("Emit", PASS_EMISSION); + MAP_PASS("Env", PASS_BACKGROUND); + MAP_PASS("AO", PASS_AO); + MAP_PASS("Shadow", PASS_SHADOW); + +#ifdef __KERNEL_DEBUG__ + MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES); + MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES); + MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS); + MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES); +#endif +#undef MAP_PASS + + return PASS_NONE; +} + +int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass) +{ + string name = b_pass.name(); + if(name.substr(0, 10) != "Denoising ") { + return -1; + } + name = name.substr(10); + +#define MAP_PASS(passname, offset) if(name == passname) return offset; + MAP_PASS("Normal", DENOISING_PASS_NORMAL); + MAP_PASS("Normal Variance", DENOISING_PASS_NORMAL_VAR); + MAP_PASS("Albedo", DENOISING_PASS_ALBEDO); + MAP_PASS("Albedo Variance", DENOISING_PASS_ALBEDO_VAR); + MAP_PASS("Depth", DENOISING_PASS_DEPTH); + MAP_PASS("Depth Variance", DENOISING_PASS_DEPTH_VAR); + MAP_PASS("Shadow A", DENOISING_PASS_SHADOW_A); + MAP_PASS("Shadow B", DENOISING_PASS_SHADOW_B); + MAP_PASS("Image", DENOISING_PASS_COLOR); + MAP_PASS("Image Variance", DENOISING_PASS_COLOR_VAR); +#undef MAP_PASS + + return -1; +} + +array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay, + BL::SceneRenderLayer& b_srlay, + const SessionParams &session_params) +{ + array<Pass> passes; + Pass::add(PASS_COMBINED, passes); + + if(!session_params.device.advanced_shading) { + return passes; + } + + /* loop over passes */ + BL::RenderLayer::passes_iterator b_pass_iter; + + for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) { + BL::RenderPass b_pass(*b_pass_iter); + PassType pass_type = get_pass_type(b_pass); + + if(pass_type == PASS_MOTION && scene->integrator->motion_blur) + continue; + if(pass_type != PASS_NONE) + Pass::add(pass_type, passes); + } + + PointerRNA crp = RNA_pointer_get(&b_srlay.ptr, "cycles"); + if(get_boolean(crp, "denoising_store_passes") && + get_boolean(crp, "use_denoising") && + !session_params.progressive_refine) { + b_engine.add_pass("Denoising Normal", 3, "XYZ", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Normal Variance", 3, "XYZ", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Albedo", 3, "RGB", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Albedo Variance", 3, "RGB", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Depth", 1, "Z", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Depth Variance", 1, "Z", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Shadow A", 3, "XYV", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Shadow B", 3, "XYV", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Image", 3, "RGB", b_srlay.name().c_str()); + b_engine.add_pass("Denoising Image Variance", 3, "RGB", b_srlay.name().c_str()); + } +#ifdef __KERNEL_DEBUG__ + if(get_boolean(crp, "pass_debug_bvh_traversed_nodes")) { + b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_srlay.name().c_str()); + Pass::add(PASS_BVH_TRAVERSED_NODES, passes); + } + if(get_boolean(crp, "pass_debug_bvh_traversed_instances")) { + b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_srlay.name().c_str()); + Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes); + } + if(get_boolean(crp, "pass_debug_bvh_intersections")) { + b_engine.add_pass("Debug BVH Intersections", 1, "X", b_srlay.name().c_str()); + Pass::add(PASS_BVH_INTERSECTIONS, passes); + } + if(get_boolean(crp, "pass_debug_ray_bounces")) { + b_engine.add_pass("Debug Ray Bounces", 1, "X", b_srlay.name().c_str()); + Pass::add(PASS_RAY_BOUNCES, passes); + } +#endif + + return passes; +} + /* Scene Parameters */ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene, diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 36bedc505af..4ec46424b5a 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -67,6 +67,9 @@ public: void **python_thread_state, const char *layer = 0); void sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer); + array<Pass> sync_render_passes(BL::RenderLayer& b_rlay, + BL::SceneRenderLayer& b_srlay, + const SessionParams &session_params); void sync_integrator(); void sync_camera(BL::RenderSettings& b_render, BL::Object& b_override, @@ -93,13 +96,15 @@ public: Camera *cam, int width, int height); + static PassType get_pass_type(BL::RenderPass& b_pass); + static int get_denoising_pass(BL::RenderPass& b_pass); + private: /* sync */ void sync_lamps(bool update_all); void sync_materials(bool update_all); - void sync_objects(BL::SpaceView3D& b_v3d, float motion_time = 0.0f); + void sync_objects(float motion_time = 0.0f); void sync_motion(BL::RenderSettings& b_render, - BL::SpaceView3D& b_v3d, BL::Object& b_override, int width, int height, void **python_thread_state); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index abdbb6be0fd..363e19f7a20 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -51,8 +51,8 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data, bool calc_undeformed, Mesh::SubdivisionType subdivision_type) { - bool subsurf_mod_show_render; - bool subsurf_mod_show_viewport; + bool subsurf_mod_show_render = false; + bool subsurf_mod_show_viewport = false; if(subdivision_type != Mesh::SUBDIVISION_NONE) { BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1]; @@ -299,7 +299,7 @@ static inline uint get_layer(const BL::Array<int, 20>& array) for(uint i = 0; i < 20; i++) if(array[i]) layer |= (1 << i); - + return layer; } @@ -434,7 +434,7 @@ static inline string get_string(PointerRNA& ptr, const char *name) string str(cstr); if(cstr != cstrbuf) MEM_freeN(cstr); - + return str; } @@ -451,7 +451,7 @@ static inline string blender_absolute_path(BL::BlendData& b_data, { if(path.size() >= 2 && path[0] == '/' && path[1] == '/') { string dirname; - + if(b_id.library()) { BL::ID b_library_id(b_id.library()); dirname = blender_absolute_path(b_data, @@ -544,7 +544,7 @@ static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob) return b_smd.domain_settings(); } } - + return BL::SmokeDomainSettings(PointerRNA_NULL); } @@ -816,4 +816,3 @@ protected: CCL_NAMESPACE_END #endif /* __BLENDER_UTIL_H__ */ - |