diff options
Diffstat (limited to 'intern/cycles')
40 files changed, 383 insertions, 219 deletions
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 5844c2480d6..dbf1bcece16 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -209,6 +209,10 @@ if(WITH_CYCLES_DEBUG) add_definitions(-DWITH_CYCLES_DEBUG) endif() +if(NOT OPENIMAGEIO_PUGIXML_FOUND) + add_definitions(-DWITH_SYSTEM_PUGIXML) +endif() + include_directories( SYSTEM ${BOOST_INCLUDE_DIR} diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 3a1c7205c34..f2db9271a89 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -358,7 +358,7 @@ static void xml_read_shader(XMLReadState& state, xml_node node) /* Background */ -static void xml_read_background(XMLReadState& state, pugi::xml_node node) +static void xml_read_background(XMLReadState& state, xml_node node) { /* Background Settings */ xml_read_node(state, state.scene->background, node); diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 3018fd5b316..1f97eff9bd0 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -234,10 +234,13 @@ def register_passes(engine, scene, srl): 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') + if crl.pass_debug_render_time: engine.register_pass(scene, srl, "Debug Render Time", 1, "X", 'VALUE') + 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') + if crl.use_pass_volume_direct: engine.register_pass(scene, srl, "VolumeDir", 3, "RGB", 'COLOR') + if crl.use_pass_volume_indirect: engine.register_pass(scene, srl, "VolumeInd", 3, "RGB", 'COLOR') cscene = scene.cycles if crl.use_denoising and crl.denoising_store_passes and not cscene.use_progressive_refine: diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2e149527066..e5084138a9c 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1189,6 +1189,24 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): default=False, update=update_render_passes, ) + cls.pass_debug_render_time = BoolProperty( + name="Debug Render Time", + description="Render time in milliseconds per sample and pixel", + default=False, + update=update_render_passes, + ) + cls.use_pass_volume_direct = BoolProperty( + name="Volume Direct", + description="Deliver direct volumetric scattering pass", + default=False, + update=update_render_passes, + ) + cls.use_pass_volume_indirect = BoolProperty( + name="Volume Indirect", + description="Deliver indirect volumetric scattering pass", + default=False, + update=update_render_passes, + ) cls.use_denoising = BoolProperty( name="Use Denoising", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 67f1029acb9..03ca1ab6c7f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -526,6 +526,10 @@ class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel): row.prop(rl, "use_pass_subsurface_direct", text="Direct", toggle=True) row.prop(rl, "use_pass_subsurface_indirect", text="Indirect", toggle=True) row.prop(rl, "use_pass_subsurface_color", text="Color", toggle=True) + col.label(text="Volume:") + row = col.row(align=True) + row.prop(crl, "use_pass_volume_direct", text="Direct", toggle=True) + row.prop(crl, "use_pass_volume_indirect", text="Indirect", toggle=True) col.separator() col.prop(rl, "use_pass_emit", text="Emission") @@ -537,8 +541,9 @@ class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel): sub.active = crl.use_denoising sub.prop(crl, "denoising_store_passes", text="Denoising") + col = layout.column() + col.prop(crl, "pass_debug_render_time") 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") diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index eb573b75e9e..f02d5496112 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -112,6 +112,7 @@ static uint object_ray_visibility(BL::Object& b_ob) void BlenderSync::sync_light(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object& b_ob, + BL::DupliObject& b_dupli_ob, Transform& tfm, bool *use_portal) { @@ -193,6 +194,13 @@ void BlenderSync::sync_light(BL::Object& b_parent, light->max_bounces = get_int(clamp, "max_bounces"); + if(b_dupli_ob) { + light->random_id = b_dupli_ob.random_id(); + } + else { + light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0); + } + if(light->type == LIGHT_AREA) light->is_portal = get_boolean(clamp, "is_portal"); else @@ -271,7 +279,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, if(object_is_light(b_ob)) { /* don't use lamps for excluded layers used as mask layer */ if(!motion && !((layer_flag & render_layer.holdout_layer) && (layer_flag & render_layer.exclude_layer))) - sync_light(b_parent, persistent_id, b_ob, tfm, use_portal); + sync_light(b_parent, persistent_id, b_ob, b_dupli_ob, tfm, use_portal); return NULL; } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 142fd5ef85b..e24ed31b926 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -496,11 +496,13 @@ PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass) MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT); MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT); MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT); + MAP_PASS("VolumeDir", PASS_VOLUME_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("VolumeInd", PASS_VOLUME_INDIRECT); MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR); MAP_PASS("GlossCol", PASS_GLOSSY_COLOR); @@ -518,6 +520,7 @@ PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass) MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS); MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES); #endif + MAP_PASS("Debug Render Time", PASS_RENDER_TIME); #undef MAP_PASS return PASS_NONE; @@ -604,6 +607,18 @@ array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay, Pass::add(PASS_RAY_BOUNCES, passes); } #endif + if(get_boolean(crp, "pass_debug_render_time")) { + b_engine.add_pass("Debug Render Time", 1, "X", b_srlay.name().c_str()); + Pass::add(PASS_RENDER_TIME, passes); + } + if(get_boolean(crp, "use_pass_volume_direct")) { + b_engine.add_pass("VolumeDir", 3, "RGB", b_srlay.name().c_str()); + Pass::add(PASS_VOLUME_DIRECT, passes); + } + if(get_boolean(crp, "use_pass_volume_indirect")) { + b_engine.add_pass("VolumeInd", 3, "RGB", b_srlay.name().c_str()); + Pass::add(PASS_VOLUME_INDIRECT, passes); + } return passes; } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 11e279b81c4..e7b71ae9310 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -131,6 +131,7 @@ private: void sync_light(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object& b_ob, + BL::DupliObject& b_dupli_ob, Transform& tfm, bool *use_portal); void sync_background_light(bool use_portal); diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 7557f584ebe..12094d58101 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -688,6 +688,8 @@ public: void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg) { + scoped_timer timer(&tile.buffers->render_time); + float *render_buffer = (float*)tile.buffer; int start_sample = tile.start_sample; int end_sample = tile.start_sample + tile.num_samples; diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index a38340cb286..d8d787ba706 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -908,7 +908,7 @@ public: cmem->texobject = 0; cmem->array = array_3d; } - else if(mem.data_height > 1) { + else if(mem.data_height > 0) { /* 2D texture, using pitch aligned linear memory. */ int alignment = 0; cuda_assert(cuDeviceGetAttribute(&alignment, CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, cuDevice)); @@ -962,7 +962,7 @@ public: resDesc.res.array.hArray = array_3d; resDesc.flags = 0; } - else if(mem.data_height > 1) { + else if(mem.data_height > 0) { resDesc.resType = CU_RESOURCE_TYPE_PITCH2D; resDesc.res.pitch2D.devPtr = mem.device_pointer; resDesc.res.pitch2D.format = format; @@ -1012,7 +1012,7 @@ public: if(array_3d) { cuda_assert(cuTexRefSetArray(texref, array_3d, CU_TRSA_OVERRIDE_FORMAT)); } - else if(mem.data_height > 1) { + else if(mem.data_height > 0) { CUDA_ARRAY_DESCRIPTOR array_desc; array_desc.Format = format; array_desc.Height = mem.data_height; @@ -1436,6 +1436,8 @@ public: void path_trace(DeviceTask& task, RenderTile& rtile, device_vector<WorkTile>& work_tiles) { + scoped_timer timer(&rtile.buffers->render_time); + if(have_error()) return; diff --git a/intern/cycles/device/opencl/opencl_mega.cpp b/intern/cycles/device/opencl/opencl_mega.cpp index 575ab73330e..ef39cfb5f7d 100644 --- a/intern/cycles/device/opencl/opencl_mega.cpp +++ b/intern/cycles/device/opencl/opencl_mega.cpp @@ -59,6 +59,8 @@ public: void path_trace(RenderTile& rtile, int sample) { + scoped_timer timer(&rtile.buffers->render_time); + /* Cast arguments to cl types. */ cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer); cl_mem d_buffer = CL_MEM_PTR(rtile.buffer); diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp index 1073cfa6bf6..2d819080674 100644 --- a/intern/cycles/device/opencl/opencl_split.cpp +++ b/intern/cycles/device/opencl/opencl_split.cpp @@ -138,6 +138,8 @@ public: while(task->acquire_tile(this, tile)) { if(tile.task == RenderTile::PATH_TRACE) { assert(tile.task == RenderTile::PATH_TRACE); + scoped_timer timer(&tile.buffers->render_time); + split_kernel->path_trace(task, tile, kgbuffer, diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 0a3f9ff23fe..e4573024e85 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -36,6 +36,22 @@ CCL_NAMESPACE_BEGIN +/* Returns the square of the roughness of the closure if it has roughness, + * 0 for singular closures and 1 otherwise. */ +ccl_device_inline float bsdf_get_roughness_sqr(const ShaderClosure *sc) +{ + if(CLOSURE_IS_BSDF_SINGULAR(sc->type)) { + return 0.0f; + } + + if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) { + MicrofacetBsdf *bsdf = (MicrofacetBsdf*) sc; + return bsdf->alpha_x*bsdf->alpha_y; + } + + return 1.0f; +} + ccl_device_forceinline int bsdf_sample(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, @@ -438,23 +454,5 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b) #endif } -/* Classifies a closure as diffuse-like or specular-like. - * This is needed for the denoising feature pass generation, - * which are written on the first bounce where more than 25% - * of the sampling weight belongs to diffuse-line closures. */ -ccl_device_inline bool bsdf_is_specular_like(ShaderClosure *sc) -{ - if(CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) { - return true; - } - - if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*) sc; - return (bsdf->alpha_x*bsdf->alpha_y <= 0.075f*0.075f); - } - - return false; -} - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index 6791c0b83cc..ec10e452148 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -119,7 +119,7 @@ ccl_device float bssrdf_cubic_eval(const float radius, const float sharpness, fl else { Rmy = powf(Rm, y); ry = powf(r, y); - ryinv = (r > 0.0f)? powf(r, 2.0f*y - 2.0f): 0.0f; + ryinv = (r > 0.0f)? powf(r, y - 1.0f): 0.0f; } const float Rmy5 = (Rmy*Rmy) * (Rmy*Rmy) * Rmy; diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 1ffc143be34..a276096a745 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -244,6 +244,17 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object) return f.y; } +/* Per lamp random number for shader variation */ + +ccl_device_inline float lamp_random_number(KernelGlobals *kg, int lamp) +{ + if(lamp == LAMP_NONE) + return 0.0f; + + float4 f = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 4); + return f.y; +} + /* Per object random number for shader variation */ ccl_device_inline float object_random_number(KernelGlobals *kg, int object) diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 366f25422fd..7c1b2a015e1 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -187,7 +187,6 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass) L->color_glossy = make_float3(0.0f, 0.0f, 0.0f); L->color_transmission = make_float3(0.0f, 0.0f, 0.0f); L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f); - L->color_scatter = make_float3(0.0f, 0.0f, 0.0f); L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index b31356905f2..29451b6b8b6 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -140,7 +140,7 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg, /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */ normal += sc->N * sc->sample_weight; sum_weight += sc->sample_weight; - if(!bsdf_is_specular_like(sc)) { + if(bsdf_get_roughness_sqr(sc) > sqr(0.075f)) { albedo += sc->weight; sum_nonspecular_weight += sc->sample_weight; } @@ -170,19 +170,19 @@ ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg, PathRadiance *L) { int flag = kernel_data.film.pass_flag; - if(flag & PASS_BVH_TRAVERSED_NODES) { + if(flag & PASSMASK(BVH_TRAVERSED_NODES)) { kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_nodes, L->debug_data.num_bvh_traversed_nodes); } - if(flag & PASS_BVH_TRAVERSED_INSTANCES) { + if(flag & PASSMASK(BVH_TRAVERSED_INSTANCES)) { kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_instances, L->debug_data.num_bvh_traversed_instances); } - if(flag & PASS_BVH_INTERSECTIONS) { + if(flag & PASSMASK(BVH_INTERSECTIONS)) { kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_intersections, L->debug_data.num_bvh_intersections); } - if(flag & PASS_RAY_BOUNCES) { + if(flag & PASSMASK(RAY_BOUNCES)) { kernel_write_pass_float(buffer + kernel_data.film.pass_ray_bounces, L->debug_data.num_ray_bounces); } @@ -199,8 +199,9 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl return; int flag = kernel_data.film.pass_flag; + int light_flag = kernel_data.film.light_pass_flag; - if(!(flag & PASS_ALL)) + if(!((flag | light_flag) & PASS_ANY)) return; if(!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) { @@ -209,29 +210,29 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold) { if(state->sample == 0) { - if(flag & PASS_DEPTH) { + if(flag & PASSMASK(DEPTH)) { float depth = camera_distance(kg, sd->P); kernel_write_pass_float(buffer + kernel_data.film.pass_depth, depth); } - if(flag & PASS_OBJECT_ID) { + if(flag & PASSMASK(OBJECT_ID)) { float id = object_pass_id(kg, sd->object); kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, id); } - if(flag & PASS_MATERIAL_ID) { + if(flag & PASSMASK(MATERIAL_ID)) { float id = shader_pass_id(kg, sd); kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, id); } } - if(flag & PASS_NORMAL) { + if(flag & PASSMASK(NORMAL)) { float3 normal = shader_bsdf_average_normal(kg, sd); kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, normal); } - if(flag & PASS_UV) { + if(flag & PASSMASK(UV)) { float3 uv = primitive_uv(kg, sd); kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, uv); } - if(flag & PASS_MOTION) { + if(flag & PASSMASK(MOTION)) { float4 speed = primitive_motion_vector(kg, sd); kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, speed); kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, 1.0f); @@ -241,16 +242,16 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl } } - if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT)) + if(light_flag & PASSMASK_COMPONENT(DIFFUSE)) L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput; - if(flag & (PASS_GLOSSY_INDIRECT|PASS_GLOSSY_COLOR|PASS_GLOSSY_DIRECT)) + if(light_flag & PASSMASK_COMPONENT(GLOSSY)) L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput; - if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT)) + if(light_flag & PASSMASK_COMPONENT(TRANSMISSION)) L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput; - if(flag & (PASS_SUBSURFACE_INDIRECT|PASS_SUBSURFACE_COLOR|PASS_SUBSURFACE_DIRECT)) + if(light_flag & PASSMASK_COMPONENT(SUBSURFACE)) L->color_subsurface += shader_bsdf_subsurface(kg, sd)*throughput; - if(flag & PASS_MIST) { + if(light_flag & PASSMASK(MIST)) { /* bring depth into 0..1 range */ float mist_start = kernel_data.film.mist_start; float mist_inv_depth = kernel_data.film.mist_inv_depth; @@ -280,49 +281,53 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L) { #ifdef __PASSES__ - int flag = kernel_data.film.pass_flag; + int light_flag = kernel_data.film.light_pass_flag; if(!kernel_data.film.use_light_pass) return; - if(flag & PASS_DIFFUSE_INDIRECT) + if(light_flag & PASSMASK(DIFFUSE_INDIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, L->indirect_diffuse); - if(flag & PASS_GLOSSY_INDIRECT) + if(light_flag & PASSMASK(GLOSSY_INDIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, L->indirect_glossy); - if(flag & PASS_TRANSMISSION_INDIRECT) + if(light_flag & PASSMASK(TRANSMISSION_INDIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, L->indirect_transmission); - if(flag & PASS_SUBSURFACE_INDIRECT) + if(light_flag & PASSMASK(SUBSURFACE_INDIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect, L->indirect_subsurface); - if(flag & PASS_DIFFUSE_DIRECT) + if(light_flag & PASSMASK(VOLUME_INDIRECT)) + kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_indirect, L->indirect_scatter); + if(light_flag & PASSMASK(DIFFUSE_DIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, L->direct_diffuse); - if(flag & PASS_GLOSSY_DIRECT) + if(light_flag & PASSMASK(GLOSSY_DIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, L->direct_glossy); - if(flag & PASS_TRANSMISSION_DIRECT) + if(light_flag & PASSMASK(TRANSMISSION_DIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, L->direct_transmission); - if(flag & PASS_SUBSURFACE_DIRECT) + if(light_flag & PASSMASK(SUBSURFACE_DIRECT)) kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct, L->direct_subsurface); + if(light_flag & PASSMASK(VOLUME_DIRECT)) + kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_direct, L->direct_scatter); - if(flag & PASS_EMISSION) + if(light_flag & PASSMASK(EMISSION)) kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, L->emission); - if(flag & PASS_BACKGROUND) + if(light_flag & PASSMASK(BACKGROUND)) kernel_write_pass_float3(buffer + kernel_data.film.pass_background, L->background); - if(flag & PASS_AO) + if(light_flag & PASSMASK(AO)) kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, L->ao); - if(flag & PASS_DIFFUSE_COLOR) + if(light_flag & PASSMASK(DIFFUSE_COLOR)) kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, L->color_diffuse); - if(flag & PASS_GLOSSY_COLOR) + if(light_flag & PASSMASK(GLOSSY_COLOR)) kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, L->color_glossy); - if(flag & PASS_TRANSMISSION_COLOR) + if(light_flag & PASSMASK(TRANSMISSION_COLOR)) kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, L->color_transmission); - if(flag & PASS_SUBSURFACE_COLOR) + if(light_flag & PASSMASK(SUBSURFACE_COLOR)) kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, L->color_subsurface); - if(flag & PASS_SHADOW) { + if(light_flag & PASSMASK(SHADOW)) { float4 shadow = L->shadow; shadow.w = kernel_data.film.pass_shadow_scale; kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, shadow); } - if(flag & PASS_MIST) + if(light_flag & PASSMASK(MIST)) kernel_write_pass_float(buffer + kernel_data.film.pass_mist, 1.0f - L->mist); #endif } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c43cdedac3b..45c9764cc99 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -59,6 +59,11 @@ ccl_device_forceinline bool kernel_path_scene_intersect( { uint visibility = path_state_ray_visibility(kg, state); + if(path_state_ao_bounce(kg, state)) { + visibility = PATH_RAY_SHADOW; + ray->t = kernel_data.background.ao_distance; + } + #ifdef __HAIR__ float difl = 0.0f, extmax = 0.0f; uint lcg_state = 0; @@ -74,11 +79,6 @@ ccl_device_forceinline bool kernel_path_scene_intersect( lcg_state = lcg_state_init_addrspace(state, 0x51633e2d); } - if(path_state_ao_bounce(kg, state)) { - visibility = PATH_RAY_SHADOW; - ray->t = kernel_data.background.ao_distance; - } - bool hit = scene_intersect(kg, *ray, visibility, isect, &lcg_state, difl, extmax); #else bool hit = scene_intersect(kg, *ray, visibility, isect, NULL, 0.0f, 0.0f); @@ -185,7 +185,7 @@ ccl_device_forceinline bool kernel_path_background_setup( L->transparent += average(throughput); #ifdef __PASSES__ - if(!(kernel_data.film.pass_flag & PASS_BACKGROUND)) + if(!(kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND))) #endif /* __PASSES__ */ return false; } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 3c84938a349..eb2d87bd358 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -57,6 +57,7 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg, #ifdef __INSTANCING__ sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object; #endif + sd->lamp = LAMP_NONE; sd->type = isect->type; sd->flag = 0; @@ -265,6 +266,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, #ifdef __INSTANCING__ sd->object = object; #endif + sd->lamp = LAMP_NONE; /* currently no access to bvh prim index for strand sd->prim*/ sd->prim = prim; #ifdef __UV__ @@ -286,6 +288,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, else if(lamp != LAMP_NONE) { sd->ob_tfm = lamp_fetch_transform(kg, lamp, false); sd->ob_itfm = lamp_fetch_transform(kg, lamp, true); + sd->lamp = lamp; #endif } @@ -391,6 +394,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat #ifdef __INSTANCING__ sd->object = PRIM_NONE; #endif + sd->lamp = LAMP_NONE; sd->prim = PRIM_NONE; #ifdef __UV__ sd->u = 0.0f; @@ -431,6 +435,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s # ifdef __INSTANCING__ sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */ # endif + sd->lamp = LAMP_NONE; sd->prim = PRIM_NONE; sd->type = PRIMITIVE_NONE; @@ -1190,6 +1195,7 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg, /* setup shaderdata from stack. it's mostly setup already in * shader_setup_from_volume, this switching should be quick */ sd->object = stack[i].object; + sd->lamp = LAMP_NONE; sd->shader = stack[i].shader; sd->flag &= ~SD_SHADER_FLAGS; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index e1fdd1340db..0b878f17880 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -368,43 +368,59 @@ typedef enum ClosureLabel { /* Render Passes */ +#define PASS_NAME_JOIN(a, b) a ## _ ## b +#define PASSMASK(pass) (1 << ((PASS_NAME_JOIN(PASS, pass)) % 32)) + +#define PASSMASK_COMPONENT(comp) (PASSMASK(PASS_NAME_JOIN(comp, DIRECT)) | \ + PASSMASK(PASS_NAME_JOIN(comp, INDIRECT)) | \ + PASSMASK(PASS_NAME_JOIN(comp, COLOR))) + typedef enum PassType { PASS_NONE = 0, - PASS_COMBINED = (1 << 0), - PASS_DEPTH = (1 << 1), - PASS_NORMAL = (1 << 2), - PASS_UV = (1 << 3), - PASS_OBJECT_ID = (1 << 4), - PASS_MATERIAL_ID = (1 << 5), - PASS_DIFFUSE_COLOR = (1 << 6), - PASS_GLOSSY_COLOR = (1 << 7), - PASS_TRANSMISSION_COLOR = (1 << 8), - PASS_DIFFUSE_INDIRECT = (1 << 9), - PASS_GLOSSY_INDIRECT = (1 << 10), - PASS_TRANSMISSION_INDIRECT = (1 << 11), - PASS_DIFFUSE_DIRECT = (1 << 12), - PASS_GLOSSY_DIRECT = (1 << 13), - PASS_TRANSMISSION_DIRECT = (1 << 14), - PASS_EMISSION = (1 << 15), - PASS_BACKGROUND = (1 << 16), - PASS_AO = (1 << 17), - PASS_SHADOW = (1 << 18), - PASS_MOTION = (1 << 19), - PASS_MOTION_WEIGHT = (1 << 20), - PASS_MIST = (1 << 21), - PASS_SUBSURFACE_DIRECT = (1 << 22), - PASS_SUBSURFACE_INDIRECT = (1 << 23), - PASS_SUBSURFACE_COLOR = (1 << 24), - PASS_LIGHT = (1 << 25), /* no real pass, used to force use_light_pass */ + + /* Main passes */ + PASS_COMBINED = 1, + PASS_DEPTH, + PASS_NORMAL, + PASS_UV, + PASS_OBJECT_ID, + PASS_MATERIAL_ID, + PASS_MOTION, + PASS_MOTION_WEIGHT, #ifdef __KERNEL_DEBUG__ - PASS_BVH_TRAVERSED_NODES = (1 << 26), - PASS_BVH_TRAVERSED_INSTANCES = (1 << 27), - PASS_BVH_INTERSECTIONS = (1 << 28), - PASS_RAY_BOUNCES = (1 << 29), + PASS_BVH_TRAVERSED_NODES, + PASS_BVH_TRAVERSED_INSTANCES, + PASS_BVH_INTERSECTIONS, + PASS_RAY_BOUNCES, #endif + PASS_RENDER_TIME, + PASS_CATEGORY_MAIN_END = 31, + + PASS_MIST = 32, + PASS_EMISSION, + PASS_BACKGROUND, + PASS_AO, + PASS_SHADOW, + PASS_LIGHT, /* no real pass, used to force use_light_pass */ + PASS_DIFFUSE_DIRECT, + PASS_DIFFUSE_INDIRECT, + PASS_DIFFUSE_COLOR, + PASS_GLOSSY_DIRECT, + PASS_GLOSSY_INDIRECT, + PASS_GLOSSY_COLOR, + PASS_TRANSMISSION_DIRECT, + PASS_TRANSMISSION_INDIRECT, + PASS_TRANSMISSION_COLOR, + PASS_SUBSURFACE_DIRECT, + PASS_SUBSURFACE_INDIRECT, + PASS_SUBSURFACE_COLOR, + PASS_VOLUME_DIRECT, + PASS_VOLUME_INDIRECT, + /* No Scatter color since it's tricky to define what it would even mean. */ + PASS_CATEGORY_LIGHT_END = 63, } PassType; -#define PASS_ALL (~0) +#define PASS_ANY (~0) typedef enum DenoisingPassOffsets { DENOISING_PASS_NORMAL = 0, @@ -509,7 +525,6 @@ typedef ccl_addr_space struct PathRadiance { float3 color_glossy; float3 color_transmission; float3 color_subsurface; - float3 color_scatter; float3 direct_diffuse; float3 direct_glossy; @@ -966,6 +981,8 @@ typedef ccl_addr_space struct ShaderData { float v; /* object id if there is one, ~0 otherwise */ int object; + /* lamp id if there is one, ~0 otherwise */ + int lamp; /* motion blur sample time */ float time; @@ -1186,6 +1203,7 @@ static_assert_align(KernelCamera, 16); typedef struct KernelFilm { float exposure; int pass_flag; + int light_pass_flag; int pass_stride; int use_light_pass; @@ -1208,11 +1226,13 @@ typedef struct KernelFilm { int pass_glossy_indirect; int pass_transmission_indirect; int pass_subsurface_indirect; + int pass_volume_indirect; int pass_diffuse_direct; int pass_glossy_direct; int pass_transmission_direct; int pass_subsurface_direct; + int pass_volume_direct; int pass_emission; int pass_background; @@ -1222,7 +1242,6 @@ typedef struct KernelFilm { int pass_shadow; float pass_shadow_scale; int filter_table_offset; - int pass_pad2; int pass_mist; float mist_start; @@ -1232,7 +1251,8 @@ typedef struct KernelFilm { int pass_denoising_data; int pass_denoising_clean; int denoising_flags; - int pad; + + int pad1, pad2, pad3; #ifdef __KERNEL_DEBUG__ int pass_bvh_traversed_nodes; diff --git a/intern/cycles/kernel/kernels/cuda/kernel_config.h b/intern/cycles/kernel/kernels/cuda/kernel_config.h index 7ae205b7e14..94f59ff38d9 100644 --- a/intern/cycles/kernel/kernels/cuda/kernel_config.h +++ b/intern/cycles/kernel/kernels/cuda/kernel_config.h @@ -73,9 +73,15 @@ /* tunable parameters */ # define CUDA_THREADS_BLOCK_WIDTH 16 -# define CUDA_KERNEL_MAX_REGISTERS 48 +/* CUDA 9.0 seems to cause slowdowns on high-end Pascal cards unless we increase the number of registers */ +# if __CUDACC_VER_MAJOR__ == 9 && __CUDA_ARCH__ >= 600 +# define CUDA_KERNEL_MAX_REGISTERS 64 +# else +# define CUDA_KERNEL_MAX_REGISTERS 48 +# endif # define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63 + /* unknown architecture */ #else # error "Unknown or unsupported CUDA architecture, can't determine launch bounds" diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index e3e85705ebc..597d25e9f30 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -232,7 +232,11 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O /* optimization: it's possible to not use a prepare function at all and * only initialize the actual class when accessing the closure component * data, but then we need to map the id to the class somehow */ +#if OSL_LIBRARY_VERSION_CODE >= 10900 + ss->register_closure(name, id, params, prepare, NULL); +#else ss->register_closure(name, id, params, prepare, NULL, 16); +#endif } void OSLShader::register_closures(OSLShadingSystem *ss_) diff --git a/intern/cycles/kernel/split/kernel_branched.h b/intern/cycles/kernel/split/kernel_branched.h index 6456636caaa..368a4395760 100644 --- a/intern/cycles/kernel/split/kernel_branched.h +++ b/intern/cycles/kernel/split/kernel_branched.h @@ -33,9 +33,9 @@ ccl_device_inline void kernel_split_branched_path_indirect_loop_init(KernelGloba BRANCHED_STORE(isect); BRANCHED_STORE(ray_state); - branched_state->sd = *kernel_split_sd(sd, ray_index); - for(int i = 0; i < branched_state->sd.num_closure; i++) { - branched_state->sd.closure[i] = kernel_split_sd(sd, ray_index)->closure[i]; + *kernel_split_sd(branched_state_sd, ray_index) = *kernel_split_sd(sd, ray_index); + for(int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) { + kernel_split_sd(branched_state_sd, ray_index)->closure[i] = kernel_split_sd(sd, ray_index)->closure[i]; } #undef BRANCHED_STORE @@ -60,9 +60,9 @@ ccl_device_inline void kernel_split_branched_path_indirect_loop_end(KernelGlobal BRANCHED_RESTORE(isect); BRANCHED_RESTORE(ray_state); - *kernel_split_sd(sd, ray_index) = branched_state->sd; - for(int i = 0; i < branched_state->sd.num_closure; i++) { - kernel_split_sd(sd, ray_index)->closure[i] = branched_state->sd.closure[i]; + *kernel_split_sd(sd, ray_index) = *kernel_split_sd(branched_state_sd, ray_index); + for(int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) { + kernel_split_sd(sd, ray_index)->closure[i] = kernel_split_sd(branched_state_sd, ray_index)->closure[i]; } #undef BRANCHED_RESTORE @@ -83,10 +83,17 @@ ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals } #define SPLIT_DATA_ENTRY(type, name, num) \ - kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index]; + if(num) { \ + kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index]; \ + } SPLIT_DATA_ENTRIES_BRANCHED_SHARED #undef SPLIT_DATA_ENTRY + *kernel_split_sd(sd, inactive_ray) = *kernel_split_sd(sd, ray_index); + for(int i = 0; i < kernel_split_sd(sd, ray_index)->num_closure; i++) { + kernel_split_sd(sd, inactive_ray)->closure[i] = kernel_split_sd(sd, ray_index)->closure[i]; + } + kernel_split_state.branched_state[inactive_ray].shared_sample_count = 0; kernel_split_state.branched_state[inactive_ray].original_ray = ray_index; kernel_split_state.branched_state[inactive_ray].waiting_on_shared_samples = false; diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h index bb6bf1cc7e6..75a0af7567b 100644 --- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h +++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h @@ -145,7 +145,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, if(kernel_split_branched_path_surface_indirect_light_iter(kg, ray_index, 1.0f, - &kernel_split_state.branched_state[ray_index].sd, + kernel_split_sd(branched_state_sd, ray_index), true, true)) { @@ -190,7 +190,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, if(kernel_split_branched_path_surface_indirect_light_iter(kg, ray_index, 1.0f, - &kernel_split_state.branched_state[ray_index].sd, + kernel_split_sd(branched_state_sd, ray_index), true, true)) { diff --git a/intern/cycles/kernel/split/kernel_split_data.h b/intern/cycles/kernel/split/kernel_split_data.h index fa2f0b20a83..9297e1e0ad5 100644 --- a/intern/cycles/kernel/split/kernel_split_data.h +++ b/intern/cycles/kernel/split/kernel_split_data.h @@ -34,7 +34,7 @@ ccl_device_inline uint64_t split_data_buffer_size(KernelGlobals *kg, size_t num_ uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures-1); #ifdef __BRANCHED_PATH__ - size += align_up(closure_size * num_elements, 16); + size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16); #endif size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16); @@ -60,7 +60,8 @@ ccl_device_inline void split_data_init(KernelGlobals *kg, uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures-1); #ifdef __BRANCHED_PATH__ - p += align_up(closure_size * num_elements, 16); + split_data->_branched_state_sd = (ShaderData*)p; + p += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16); #endif split_data->_sd = (ShaderData*)p; diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h index dab0bf72fcf..9970ec1315c 100644 --- a/intern/cycles/kernel/split/kernel_split_data_types.h +++ b/intern/cycles/kernel/split/kernel_split_data_types.h @@ -85,13 +85,11 @@ typedef ccl_global struct SplitBranchedState { int shared_sample_count; /* number of branched samples shared with other threads */ int original_ray; /* index of original ray when sharing branched samples */ bool waiting_on_shared_samples; - - /* Must be last in to allow for dynamic size of closures */ - struct ShaderData sd; } SplitBranchedState; #define SPLIT_DATA_BRANCHED_ENTRIES \ - SPLIT_DATA_ENTRY( SplitBranchedState, branched_state, 1) + SPLIT_DATA_ENTRY( SplitBranchedState, branched_state, 1) \ + SPLIT_DATA_ENTRY(ShaderData, _branched_state_sd, 0) #else #define SPLIT_DATA_BRANCHED_ENTRIES #endif /* __BRANCHED_PATH__ */ diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h index 887c3e313d1..5bf7483e9a2 100644 --- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h +++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h @@ -37,7 +37,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it { SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; - ShaderData *sd = &branched_state->sd; + ShaderData *sd = kernel_split_sd(branched_state_sd, ray_index); PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]); diff --git a/intern/cycles/kernel/svm/svm_bevel.h b/intern/cycles/kernel/svm/svm_bevel.h index 65afe1f74ec..bbbc8dce2cf 100644 --- a/intern/cycles/kernel/svm/svm_bevel.h +++ b/intern/cycles/kernel/svm/svm_bevel.h @@ -198,7 +198,7 @@ ccl_device_noinline float3 svm_bevel( /* Normalize. */ float3 N = safe_normalize(sum_N); - return is_zero(N) ? sd->N : N; + return is_zero(N) ? sd->N : (sd->flag & SD_BACKFACING) ? -N : N; } ccl_device void svm_node_bevel( diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h index 14245cf0522..90fa2a99b67 100644 --- a/intern/cycles/kernel/svm/svm_brick.h +++ b/intern/cycles/kernel/svm/svm_brick.h @@ -18,9 +18,9 @@ CCL_NAMESPACE_BEGIN /* Brick */ -ccl_device_noinline float brick_noise(int n) /* fast integer noise */ +ccl_device_noinline float brick_noise(uint n) /* fast integer noise */ { - int nn; + uint nn; n = (n + 1013) & 0x7fffffff; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index cce4e89e715..9af4a0182d9 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -90,7 +90,15 @@ ccl_device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *s } case NODE_INFO_OB_INDEX: data = object_pass_id(kg, sd->object); break; case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break; - case NODE_INFO_OB_RANDOM: data = object_random_number(kg, sd->object); break; + case NODE_INFO_OB_RANDOM: { + if(sd->lamp != LAMP_NONE) { + data = lamp_random_number(kg, sd->lamp); + } + else { + data = object_random_number(kg, sd->object); + } + break; + } default: data = 0.0f; break; } diff --git a/intern/cycles/kernel/svm/svm_gradient.h b/intern/cycles/kernel/svm/svm_gradient.h index 53d7b4f812c..74e36e70427 100644 --- a/intern/cycles/kernel/svm/svm_gradient.h +++ b/intern/cycles/kernel/svm/svm_gradient.h @@ -46,7 +46,10 @@ ccl_device float svm_gradient(float3 p, NodeGradientType type) return atan2f(y, x) / M_2PI_F + 0.5f; } else { - float r = fmaxf(1.0f - sqrtf(x*x + y*y + z*z), 0.0f); + /* Bias a little bit for the case where p is a unit length vector, + * to get exactly zero instead of a small random value depending + * on float precision. */ + float r = fmaxf(0.999999f - sqrtf(x*x + y*y + z*z), 0.0f); if(type == NODE_BLEND_QUADRATIC_SPHERE) return r*r; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index f08ec76c055..c7fe7948422 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -465,13 +465,16 @@ typedef enum ClosureType { #define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) #define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID) #define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID) +#define CLOSURE_IS_BSDF_SINGULAR(type) (type == CLOSURE_BSDF_REFLECTION_ID || \ + type == CLOSURE_BSDF_REFRACTION_ID || \ + type == CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID) -#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) #define CLOSURE_IS_BSDF_MULTISCATTER(type) (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID ||\ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) -#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\ - (type >= CLOSURE_BSDF_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)) +#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\ + (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) ||\ + (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) #define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_BURLEY_ID) #define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID) #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index ac675dc7b39..5c7729ec89f 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -116,7 +116,7 @@ RenderTile::RenderTile() RenderBuffers::RenderBuffers(Device *device) : buffer(device, "RenderBuffers", MEM_READ_WRITE), - map_neighbor_copied(false) + map_neighbor_copied(false), render_time(0.0f) { } @@ -236,10 +236,17 @@ bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int int size = params.width*params.height; - if(components == 1) { + if(components == 1 && type == PASS_RENDER_TIME) { + /* Render time is not stored by kernel, but measured per tile. */ + float val = (float) (1000.0 * render_time/(params.width * params.height * sample)); + for(int i = 0; i < size; i++, pixels++) { + pixels[0] = val; + } + } + else if(components == 1) { assert(pass.components == components); - /* scalar */ + /* Scalar */ if(type == PASS_DEPTH) { for(int i = 0; i < size; i++, in += pass_stride, pixels++) { float f = *in; diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 9fa0cdd4e27..028bfb83735 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -75,6 +75,7 @@ public: /* float buffer */ device_vector<float> buffer; bool map_neighbor_copied; + double render_time; explicit RenderBuffers(Device *device); ~RenderBuffers(); diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index c8213d258d5..6c8c929c2f9 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -85,83 +85,81 @@ void Pass::add(PassType type, array<Pass>& passes) pass.components = 1; pass.filter = false; break; - case PASS_DIFFUSE_COLOR: - case PASS_GLOSSY_COLOR: - case PASS_TRANSMISSION_COLOR: - case PASS_SUBSURFACE_COLOR: - pass.components = 4; - break; - case PASS_DIFFUSE_INDIRECT: + + case PASS_EMISSION: + case PASS_BACKGROUND: pass.components = 4; pass.exposure = true; - pass.divide_type = PASS_DIFFUSE_COLOR; break; - case PASS_GLOSSY_INDIRECT: + case PASS_AO: pass.components = 4; - pass.exposure = true; - pass.divide_type = PASS_GLOSSY_COLOR; break; - case PASS_TRANSMISSION_INDIRECT: + case PASS_SHADOW: pass.components = 4; - pass.exposure = true; - pass.divide_type = PASS_TRANSMISSION_COLOR; + pass.exposure = false; break; - case PASS_SUBSURFACE_INDIRECT: + case PASS_LIGHT: + /* This isn't a real pass, used by baking to see whether + * light data is needed or not. + * + * Set components to 0 so pass sort below happens in a + * determined way. + */ + pass.components = 0; + break; +#ifdef WITH_CYCLES_DEBUG + case PASS_BVH_TRAVERSED_NODES: + case PASS_BVH_TRAVERSED_INSTANCES: + case PASS_BVH_INTERSECTIONS: + case PASS_RAY_BOUNCES: + pass.components = 1; + pass.exposure = false; + break; +#endif + case PASS_RENDER_TIME: + /* This pass is handled entirely on the host side. */ + pass.components = 0; + break; + + case PASS_DIFFUSE_COLOR: + case PASS_GLOSSY_COLOR: + case PASS_TRANSMISSION_COLOR: + case PASS_SUBSURFACE_COLOR: pass.components = 4; - pass.exposure = true; - pass.divide_type = PASS_SUBSURFACE_COLOR; break; case PASS_DIFFUSE_DIRECT: + case PASS_DIFFUSE_INDIRECT: pass.components = 4; pass.exposure = true; pass.divide_type = PASS_DIFFUSE_COLOR; break; case PASS_GLOSSY_DIRECT: + case PASS_GLOSSY_INDIRECT: pass.components = 4; pass.exposure = true; pass.divide_type = PASS_GLOSSY_COLOR; break; case PASS_TRANSMISSION_DIRECT: + case PASS_TRANSMISSION_INDIRECT: pass.components = 4; pass.exposure = true; pass.divide_type = PASS_TRANSMISSION_COLOR; break; case PASS_SUBSURFACE_DIRECT: + case PASS_SUBSURFACE_INDIRECT: pass.components = 4; pass.exposure = true; pass.divide_type = PASS_SUBSURFACE_COLOR; break; - - case PASS_EMISSION: - case PASS_BACKGROUND: + case PASS_VOLUME_DIRECT: + case PASS_VOLUME_INDIRECT: pass.components = 4; pass.exposure = true; break; - case PASS_AO: - pass.components = 4; - break; - case PASS_SHADOW: - pass.components = 4; - pass.exposure = false; - break; - case PASS_LIGHT: - /* This isn't a real pass, used by baking to see whether - * light data is needed or not. - * - * Set components to 0 so pass sort below happens in a - * determined way. - */ - pass.components = 0; - break; -#ifdef WITH_CYCLES_DEBUG - case PASS_BVH_TRAVERSED_NODES: - case PASS_BVH_TRAVERSED_INSTANCES: - case PASS_BVH_INTERSECTIONS: - case PASS_RAY_BOUNCES: - pass.components = 1; - pass.exposure = false; + + default: + assert(false); break; -#endif } passes.push_back_slow(pass); @@ -318,7 +316,19 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) for(size_t i = 0; i < passes.size(); i++) { Pass& pass = passes[i]; - kfilm->pass_flag |= pass.type; + + if(pass.type == PASS_NONE) + continue; + + int pass_flag = (1 << (pass.type % 32)); + if(pass.type <= PASS_CATEGORY_MAIN_END) { + kfilm->pass_flag |= pass_flag; + } + else { + assert(pass.type <= PASS_CATEGORY_LIGHT_END); + kfilm->use_light_pass = 1; + kfilm->light_pass_flag |= pass_flag; + } switch(pass.type) { case PASS_COMBINED: @@ -327,10 +337,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) case PASS_DEPTH: kfilm->pass_depth = kfilm->pass_stride; break; - case PASS_MIST: - kfilm->pass_mist = kfilm->pass_stride; - kfilm->use_light_pass = 1; - break; case PASS_NORMAL: kfilm->pass_normal = kfilm->pass_stride; break; @@ -349,74 +355,67 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) case PASS_MATERIAL_ID: kfilm->pass_material_id = kfilm->pass_stride; break; + + case PASS_MIST: + kfilm->pass_mist = kfilm->pass_stride; + break; + case PASS_EMISSION: + kfilm->pass_emission = kfilm->pass_stride; + break; + case PASS_BACKGROUND: + kfilm->pass_background = kfilm->pass_stride; + break; + case PASS_AO: + kfilm->pass_ao = kfilm->pass_stride; + break; + case PASS_SHADOW: + kfilm->pass_shadow = kfilm->pass_stride; + break; + + case PASS_LIGHT: + break; + case PASS_DIFFUSE_COLOR: kfilm->pass_diffuse_color = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_GLOSSY_COLOR: kfilm->pass_glossy_color = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_TRANSMISSION_COLOR: kfilm->pass_transmission_color = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_SUBSURFACE_COLOR: kfilm->pass_subsurface_color = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_DIFFUSE_INDIRECT: kfilm->pass_diffuse_indirect = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_GLOSSY_INDIRECT: kfilm->pass_glossy_indirect = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_TRANSMISSION_INDIRECT: kfilm->pass_transmission_indirect = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_SUBSURFACE_INDIRECT: kfilm->pass_subsurface_indirect = kfilm->pass_stride; - kfilm->use_light_pass = 1; + break; + case PASS_VOLUME_INDIRECT: + kfilm->pass_volume_indirect = kfilm->pass_stride; break; case PASS_DIFFUSE_DIRECT: kfilm->pass_diffuse_direct = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_GLOSSY_DIRECT: kfilm->pass_glossy_direct = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_TRANSMISSION_DIRECT: kfilm->pass_transmission_direct = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; case PASS_SUBSURFACE_DIRECT: kfilm->pass_subsurface_direct = kfilm->pass_stride; - kfilm->use_light_pass = 1; break; - - case PASS_EMISSION: - kfilm->pass_emission = kfilm->pass_stride; - kfilm->use_light_pass = 1; - break; - case PASS_BACKGROUND: - kfilm->pass_background = kfilm->pass_stride; - kfilm->use_light_pass = 1; - break; - case PASS_AO: - kfilm->pass_ao = kfilm->pass_stride; - kfilm->use_light_pass = 1; - break; - case PASS_SHADOW: - kfilm->pass_shadow = kfilm->pass_stride; - kfilm->use_light_pass = 1; - break; - - case PASS_LIGHT: - kfilm->use_light_pass = 1; + case PASS_VOLUME_DIRECT: + kfilm->pass_volume_direct = kfilm->pass_stride; break; #ifdef WITH_CYCLES_DEBUG @@ -433,8 +432,11 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) kfilm->pass_ray_bounces = kfilm->pass_stride; break; #endif + case PASS_RENDER_TIME: + break; - case PASS_NONE: + default: + assert(false); break; } diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 9358b40a689..482442cce29 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -723,6 +723,7 @@ void ImageManager::device_load_image(Device *device, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); float *pixels = (float*)tex_img->alloc(1, 1); pixels[0] = TEX_IMAGE_MISSING_R; @@ -748,6 +749,7 @@ void ImageManager::device_load_image(Device *device, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); float *pixels = (float*)tex_img->alloc(1, 1); pixels[0] = TEX_IMAGE_MISSING_R; @@ -770,6 +772,7 @@ void ImageManager::device_load_image(Device *device, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); uchar *pixels = (uchar*)tex_img->alloc(1, 1); pixels[0] = (TEX_IMAGE_MISSING_R * 255); @@ -794,6 +797,7 @@ void ImageManager::device_load_image(Device *device, texture_limit, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); uchar *pixels = (uchar*)tex_img->alloc(1, 1); pixels[0] = (TEX_IMAGE_MISSING_R * 255); @@ -815,6 +819,7 @@ void ImageManager::device_load_image(Device *device, texture_limit, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); half *pixels = (half*)tex_img->alloc(1, 1); pixels[0] = TEX_IMAGE_MISSING_R; @@ -839,6 +844,7 @@ void ImageManager::device_load_image(Device *device, texture_limit, *tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ + thread_scoped_lock device_lock(device_mutex); half *pixels = (half*)tex_img->alloc(1, 1); pixels[0] = TEX_IMAGE_MISSING_R; diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index b37a0768b53..b62453cf5fc 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -134,6 +134,7 @@ NODE_DEFINE(Light) SOCKET_INT(samples, "Samples", 1); SOCKET_INT(max_bounces, "Max Bounces", 1024); + SOCKET_UINT(random_id, "Random ID", 0); SOCKET_BOOLEAN(is_portal, "Is Portal", false); SOCKET_BOOLEAN(is_enabled, "Is Enabled", true); @@ -638,6 +639,7 @@ void LightManager::device_update_points(Device *, int shader_id = scene->shader_manager->get_shader_id(shader); float samples = __int_as_float(light->samples); float max_bounces = __int_as_float(light->max_bounces); + float random = (float)light->random_id * (1.0f/(float)0xFFFFFFFF); if(!light->cast_shadow) shader_id &= ~SHADER_CAST_SHADOW; @@ -758,7 +760,7 @@ void LightManager::device_update_points(Device *, light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); + light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, random, 0.0f, 0.0f); Transform tfm = light->tfm; Transform itfm = transform_inverse(tfm); diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 7e9014eb823..97b7b971c73 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -70,6 +70,7 @@ public: Shader *shader; int samples; int max_bounces; + uint random_id; void tag_update(Scene *scene); diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index fb04d49bcd9..39ce6a93982 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -518,6 +518,11 @@ ccl_device float safe_modulo(float a, float b) return (b != 0.0f)? fmodf(a, b): 0.0f; } +ccl_device_inline float sqr(float a) +{ + return a * a; +} + ccl_device_inline float beta(float x, float y) { #ifndef __KERNEL_OPENCL__ diff --git a/intern/cycles/util/util_xml.h b/intern/cycles/util/util_xml.h index e1a28df9433..6f06f17937b 100644 --- a/intern/cycles/util/util_xml.h +++ b/intern/cycles/util/util_xml.h @@ -23,10 +23,19 @@ CCL_NAMESPACE_BEGIN -using OIIO_NAMESPACE::pugi::xml_node; -using OIIO_NAMESPACE::pugi::xml_attribute; +OIIO_NAMESPACE_USING + +#ifdef WITH_SYSTEM_PUGIXML +# define PUGIXML_NAMESPACE pugi +#else +# define PUGIXML_NAMESPACE OIIO_NAMESPACE::pugi +#endif + +using PUGIXML_NAMESPACE::xml_attribute; +using PUGIXML_NAMESPACE::xml_document; +using PUGIXML_NAMESPACE::xml_node; +using PUGIXML_NAMESPACE::xml_parse_result; CCL_NAMESPACE_END #endif /* __UTIL_XML_H__ */ - |