diff options
Diffstat (limited to 'intern')
32 files changed, 273 insertions, 117 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 6c001f8889b..431796e106b 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -304,7 +304,8 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node) xml_read_int(&integrator->volume_max_steps, node, "volume_max_steps"); /* Various Settings */ - xml_read_bool(&integrator->no_caustics, node, "no_caustics"); + xml_read_bool(&integrator->caustics_reflective, node, "caustics_reflective"); + xml_read_bool(&integrator->caustics_refractive, node, "caustics_refractive"); xml_read_float(&integrator->filter_glossy, node, "filter_glossy"); xml_read_int(&integrator->seed, node, "seed"); diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py index 84be09a8ff4..2ec65d7183a 100644 --- a/intern/cycles/blender/addon/presets.py +++ b/intern/cycles/blender/addon/presets.py @@ -33,13 +33,16 @@ class AddPresetIntegrator(AddPresetBase, Operator): preset_values = [ "cycles.max_bounces", "cycles.min_bounces", - "cycles.no_caustics", "cycles.diffuse_bounces", "cycles.glossy_bounces", "cycles.transmission_bounces", "cycles.volume_bounces", "cycles.transparent_min_bounces", - "cycles.transparent_max_bounces" + "cycles.transparent_max_bounces", + "cycles.use_transparent_shadows", + "cycles.caustics_reflective", + "cycles.caustics_refractive", + "cycles.blur_glossy" ] preset_subdir = "cycles/integrator" @@ -67,10 +70,13 @@ class AddPresetSampling(AddPresetBase, Operator): "cycles.mesh_light_samples", "cycles.subsurface_samples", "cycles.volume_samples", - "cycles.no_caustics", - "cycles.blur_glossy", "cycles.use_square_samples", - "cycles.progressive" + "cycles.progressive", + "cycles.seed", + "cycles.sample_clamp_direct", + "cycles.sample_clamp_indirect", + "cycles.sample_all_lights_direct", + "cycles.sample_all_lights_indirect", ] preset_subdir = "cycles/sampling" diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 59e60a9eef1..0ac0e0f091e 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -259,11 +259,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=True, ) - cls.no_caustics = BoolProperty( - name="No Caustics", - description="Leave out caustics, resulting in a darker image with less noise", - default=False, + cls.caustics_reflective = BoolProperty( + name="Reflective Caustics", + description="Use reflective caustics, resulting in a brighter image (more noise but added realism)", + default=True, + ) + + cls.caustics_refractive = BoolProperty( + name="Refractive Caustics", + description="Use refractive caustics, resulting in a brighter image (more noise but added realism)", + default=True, ) + cls.blur_glossy = FloatProperty( name="Filter Glossy", description="Adaptively blur glossy shaders after blurry bounces, " @@ -731,6 +738,11 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup): description="Object visibility for shadow rays", default=True, ) + cls.scatter = BoolProperty( + name="Volume Scatter", + description="Object visibility for volume scatter rays", + default=True, + ) @classmethod def unregister(cls): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index aab9f83d0ed..6e40c42fb2d 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -210,7 +210,8 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): col.separator() - col.prop(cscene, "no_caustics") + col.prop(cscene, "caustics_reflective") + col.prop(cscene, "caustics_refractive") col.prop(cscene, "blur_glossy") col = split.column() @@ -618,6 +619,7 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel): flow.prop(visibility, "diffuse") flow.prop(visibility, "glossy") flow.prop(visibility, "transmission") + flow.prop(visibility, "scatter") if ob.type != 'LAMP': flow.prop(visibility, "shadow") @@ -897,6 +899,7 @@ class CyclesWorld_PT_ray_visibility(CyclesButtonsPanel, Panel): flow.prop(visibility, "diffuse") flow.prop(visibility, "glossy") flow.prop(visibility, "transmission") + flow.prop(visibility, "scatter") class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index b0b4e1d24dd..6f9509e7d99 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -33,3 +33,12 @@ def do_versions(self): cscene = scene.cycles if not cscene.is_property_set("volume_bounces"): cscene.volume_bounces = 1 + + for scene in bpy.data.scenes: + cscene = scene.cycles + if (cscene.get("no_caustics", False) and + not cscene.is_property_set("caustics_reflective") and + not cscene.is_property_set("caustics_refractive")): + + cscene.caustics_reflective = False + cscene.caustics_refractive = False diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 94dec0b8244..1e07c5f9c96 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -82,6 +82,7 @@ static uint object_ray_visibility(BL::Object b_ob) flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0; flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0; flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0; + flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0; return flag; } @@ -172,6 +173,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0; light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0; light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0; + light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0; /* tag */ light->tag_update(scene); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 193eb69173b..7752c1ce1bd 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1071,6 +1071,7 @@ void BlenderSync::sync_world(bool update_all) visibility |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0; visibility |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0; visibility |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0; + visibility |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0; background->visibility = visibility; } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index a5d6bdf1fa1..2ac90b34fd7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -180,7 +180,8 @@ void BlenderSync::sync_integrator() integrator->volume_max_steps = get_int(cscene, "volume_max_steps"); integrator->volume_step_size = get_float(cscene, "volume_step_size"); - integrator->no_caustics = get_boolean(cscene, "no_caustics"); + integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective"); + integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive"); integrator->filter_glossy = get_float(cscene, "blur_glossy"); integrator->seed = get_int(cscene, "seed"); diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index fd5ae1d7828..4623764d210 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -73,8 +73,8 @@ public: void mem_alloc(device_memory& mem, MemoryType type) { mem.device_pointer = mem.data_pointer; - - stats.mem_alloc(mem.memory_size()); + mem.device_size = mem.memory_size(); + stats.mem_alloc(mem.device_size); } void mem_copy_to(device_memory& mem) @@ -94,9 +94,11 @@ public: void mem_free(device_memory& mem) { - mem.device_pointer = 0; - - stats.mem_free(mem.memory_size()); + if(mem.device_pointer) { + mem.device_pointer = 0; + stats.mem_free(mem.device_size); + mem.device_size = 0; + } } void const_copy_to(const char *name, void *host, size_t size) @@ -108,15 +110,17 @@ public: { kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height, mem.data_depth, interpolation); mem.device_pointer = mem.data_pointer; - - stats.mem_alloc(mem.memory_size()); + mem.device_size = mem.memory_size(); + stats.mem_alloc(mem.device_size); } void tex_free(device_memory& mem) { - mem.device_pointer = 0; - - stats.mem_free(mem.memory_size()); + if(mem.device_pointer) { + mem.device_pointer = 0; + stats.mem_free(mem.device_size); + mem.device_size = 0; + } } void *osl_memory() diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 1ed26717f4b..5de2efab8be 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -334,6 +334,7 @@ public: size_t size = mem.memory_size(); cuda_assert(cuMemAlloc(&device_pointer, size)); mem.device_pointer = (device_ptr)device_pointer; + mem.device_size = size; stats.mem_alloc(size); cuda_pop_context(); } @@ -381,7 +382,8 @@ public: mem.device_pointer = 0; - stats.mem_free(mem.memory_size()); + stats.mem_free(mem.device_size); + mem.device_size = 0; } } @@ -473,6 +475,7 @@ public: cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES)); mem.device_pointer = (device_ptr)handle; + mem.device_size = size; stats.mem_alloc(size); } @@ -540,7 +543,8 @@ public: tex_interp_map.erase(tex_interp_map.find(mem.device_pointer)); mem.device_pointer = 0; - stats.mem_free(mem.memory_size()); + stats.mem_free(mem.device_size); + mem.device_size = 0; } else { tex_interp_map.erase(tex_interp_map.find(mem.device_pointer)); @@ -790,7 +794,8 @@ public: mem.device_pointer = pmem.cuTexId; pixel_mem_map[mem.device_pointer] = pmem; - stats.mem_alloc(mem.memory_size()); + mem.device_size = mem.memory_size(); + stats.mem_alloc(mem.device_size); return; } @@ -847,7 +852,8 @@ public: pixel_mem_map.erase(pixel_mem_map.find(mem.device_pointer)); mem.device_pointer = 0; - stats.mem_free(mem.memory_size()); + stats.mem_free(mem.device_size); + mem.device_size = 0; return; } diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index 8d6f4a49a9c..8eee6a2c79e 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -167,6 +167,7 @@ public: int data_elements; device_ptr data_pointer; size_t data_size; + size_t device_size; size_t data_width; size_t data_height; size_t data_depth; @@ -194,6 +195,7 @@ public: data_elements = device_type_traits<T>::num_elements; data_pointer = 0; data_size = 0; + device_size = 0; data_width = 0; data_height = 0; data_depth = 0; diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 82419cd62b1..d950d084cd4 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -794,6 +794,7 @@ public: opencl_assert_err(ciErr, "clCreateBuffer"); stats.mem_alloc(size); + mem.device_size = size; } void mem_copy_to(device_memory& mem) @@ -825,7 +826,8 @@ public: opencl_assert(clReleaseMemObject(CL_MEM_PTR(mem.device_pointer))); mem.device_pointer = 0; - stats.mem_free(mem.memory_size()); + stats.mem_free(mem.device_size); + mem.device_size = 0; } } diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h index b3dcb9dcc38..05816bac2c1 100644 --- a/intern/cycles/kernel/closure/bsdf_util.h +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -111,16 +111,20 @@ ccl_device float fresnel_dielectric_cos(float cosi, float eta) return 1.0f; // TIR(no refracted component) } -ccl_device float fresnel_conductor(float cosi, float eta, float k) +#if 0 +ccl_device float3 fresnel_conductor(float cosi, const float3 eta, const float3 k) { - float tmp_f = eta * eta + k * k; - float tmp = tmp_f * cosi * cosi; - float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/ - (tmp + (2.0f * eta * cosi) + 1); - float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/ - (tmp_f + (2.0f * eta * cosi) + cosi * cosi); + float3 cosi2 = make_float3(cosi*cosi); + float3 one = make_float3(1.0f, 1.0f, 1.0f); + float3 tmp_f = eta * eta + k * k; + float3 tmp = tmp_f * cosi2; + float3 Rparl2 = (tmp - (2.0f * eta * cosi) + one) / + (tmp + (2.0f * eta * cosi) + one); + float3 Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi2) / + (tmp_f + (2.0f * eta * cosi) + cosi2); return(Rparl2 + Rperp2) * 0.5f; } +#endif ccl_device float smooth_step(float edge0, float edge1, float x) { diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 5b2233fd336..b0efcdc66a7 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -32,10 +32,11 @@ ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 v eval->transmission = make_float3(0.0f, 0.0f, 0.0f); eval->transparent = make_float3(0.0f, 0.0f, 0.0f); eval->subsurface = make_float3(0.0f, 0.0f, 0.0f); + eval->scatter = make_float3(0.0f, 0.0f, 0.0f); if(type == CLOSURE_BSDF_TRANSPARENT_ID) eval->transparent = value; - else if(CLOSURE_IS_BSDF_DIFFUSE(type) || CLOSURE_IS_PHASE(type)) + else if(CLOSURE_IS_BSDF_DIFFUSE(type)) eval->diffuse = value; else if(CLOSURE_IS_BSDF_GLOSSY(type)) eval->glossy = value; @@ -43,6 +44,8 @@ ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 v eval->transmission = value; else if(CLOSURE_IS_BSDF_BSSRDF(type)) eval->subsurface = value; + else if(CLOSURE_IS_PHASE(type)) + eval->scatter = value; } else eval->diffuse = value; @@ -51,11 +54,17 @@ ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 v #endif } -ccl_device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value) +/* TODO(sergey): This is just a workaround for annoying 6.5 compiler bug. */ +#if !defined(__KERNEL_CUDA__) || __CUDA_ARCH__ < 500 +ccl_device_inline +#else +ccl_device_noinline +#endif +void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value) { #ifdef __PASSES__ if(eval->use_light_pass) { - if(CLOSURE_IS_BSDF_DIFFUSE(type) || CLOSURE_IS_PHASE(type)) + if(CLOSURE_IS_BSDF_DIFFUSE(type)) eval->diffuse += value; else if(CLOSURE_IS_BSDF_GLOSSY(type)) eval->glossy += value; @@ -63,6 +72,8 @@ ccl_device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 eval->transmission += value; else if(CLOSURE_IS_BSDF_BSSRDF(type)) eval->subsurface += value; + else if(CLOSURE_IS_PHASE(type)) + eval->scatter += value; /* skipping transparent, this function is used by for eval(), will be zero then */ } @@ -81,7 +92,8 @@ ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval) && is_zero(eval->glossy) && is_zero(eval->transmission) && is_zero(eval->transparent) - && is_zero(eval->subsurface); + && is_zero(eval->subsurface) + && is_zero(eval->scatter); } else return is_zero(eval->diffuse); @@ -98,6 +110,7 @@ ccl_device_inline void bsdf_eval_mul(BsdfEval *eval, float3 value) eval->glossy *= value; eval->transmission *= value; eval->subsurface *= value; + eval->scatter *= value; /* skipping transparent, this function is used by for eval(), will be zero then */ } @@ -130,21 +143,25 @@ 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); L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f); L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f); L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f); L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f); L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f); L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->path_glossy = make_float3(0.0f, 0.0f, 0.0f); L->path_transmission = make_float3(0.0f, 0.0f, 0.0f); L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->path_scatter = make_float3(0.0f, 0.0f, 0.0f); L->emission = make_float3(0.0f, 0.0f, 0.0f); L->background = make_float3(0.0f, 0.0f, 0.0f); @@ -174,14 +191,16 @@ ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throug L->path_glossy = bsdf_eval->glossy*value; L->path_transmission = bsdf_eval->transmission*value; L->path_subsurface = bsdf_eval->subsurface*value; + L->path_scatter = bsdf_eval->scatter*value; - *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface; + *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter; L->direct_throughput = *throughput; } else { /* transparent bounce before first hit, or indirectly visible through BSDF */ - float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent + bsdf_eval->subsurface)*inverse_pdf; + float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent + + bsdf_eval->subsurface + bsdf_eval->scatter) * inverse_pdf; *throughput *= sum; } } @@ -241,6 +260,7 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L, float3 through L->direct_glossy += throughput*bsdf_eval->glossy*shadow; L->direct_transmission += throughput*bsdf_eval->transmission*shadow; L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow; + L->direct_scatter += throughput*bsdf_eval->scatter*shadow; if(is_lamp) { L->shadow.x += shadow.x*shadow_fac; @@ -250,7 +270,7 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L, float3 through } else { /* indirectly visible lighting after BSDF bounce */ - float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->subsurface; + float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->subsurface + bsdf_eval->scatter; L->indirect += throughput*sum*shadow; } } @@ -291,12 +311,14 @@ ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L) L->direct_glossy += L->path_glossy*L->direct_emission; L->direct_transmission += L->path_transmission*L->direct_emission; L->direct_subsurface += L->path_subsurface*L->direct_emission; + L->direct_scatter += L->path_scatter*L->direct_emission; L->indirect = safe_divide_color(L->indirect, L->direct_throughput); L->indirect_diffuse += L->path_diffuse*L->indirect; L->indirect_glossy += L->path_glossy*L->indirect; L->indirect_transmission += L->path_transmission*L->indirect; L->indirect_subsurface += L->path_subsurface*L->indirect; + L->indirect_scatter += L->path_scatter*L->indirect; } #endif } @@ -309,6 +331,7 @@ ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L) L->path_glossy = make_float3(0.0f, 0.0f, 0.0f); L->path_transmission = make_float3(0.0f, 0.0f, 0.0f); L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->path_scatter = make_float3(0.0f, 0.0f, 0.0f); L->direct_emission = make_float3(0.0f, 0.0f, 0.0f); L->indirect = make_float3(0.0f, 0.0f, 0.0f); @@ -327,8 +350,8 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi if(L->use_light_pass) { path_radiance_sum_indirect(L); - L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->emission; - L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface; + L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission; + L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter; if(!kernel_data.background.transparent) L_direct += L->background; @@ -344,11 +367,13 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f); L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f); L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f); L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f); L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f); L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f); + L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f); L->emission = make_float3(0.0f, 0.0f, 0.0f); } @@ -368,6 +393,7 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi L->direct_glossy *= scale; L->direct_transmission *= scale; L->direct_subsurface *= scale; + L->direct_scatter *= scale; L->emission *= scale; L->background *= scale; } @@ -382,6 +408,7 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi L->indirect_glossy *= scale; L->indirect_transmission *= scale; L->indirect_subsurface *= scale; + L->indirect_scatter *= scale; } /* Sum again, after clamping */ @@ -416,11 +443,13 @@ ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance L->direct_glossy += L_sample->direct_glossy*fac; L->direct_transmission += L_sample->direct_transmission*fac; L->direct_subsurface += L_sample->direct_subsurface*fac; + L->direct_scatter += L_sample->direct_scatter*fac; L->indirect_diffuse += L_sample->indirect_diffuse*fac; L->indirect_glossy += L_sample->indirect_glossy*fac; L->indirect_transmission += L_sample->indirect_transmission*fac; L->indirect_subsurface += L_sample->indirect_subsurface*fac; + L->indirect_scatter += L_sample->indirect_scatter*fac; L->emission += L_sample->emission*fac; L->background += L_sample->background*fac; diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index bda98b84da8..4b2bb723ab6 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -108,6 +108,8 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, eval->glossy = make_float3(0.0f, 0.0f, 0.0f); if(ls->shader & SHADER_EXCLUDE_TRANSMIT) eval->transmission = make_float3(0.0f, 0.0f, 0.0f); + if(ls->shader & SHADER_EXCLUDE_SCATTER) + eval->scatter = make_float3(0.0f, 0.0f, 0.0f); } #endif @@ -187,7 +189,8 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st if(ls.shader & SHADER_EXCLUDE_ANY) { if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) || - ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT))) + ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || + ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) continue; } #endif @@ -231,7 +234,8 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *sta if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || ((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) || ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || - ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA))) + ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) || + ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) return make_float3(0.0f, 0.0f, 0.0f); } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 65755f0df12..515854b6e9c 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -154,7 +154,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, #ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, L, 1.0f); + kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, L); /* indirect light bounce */ if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, L, &ray)) @@ -541,7 +541,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, #ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L, 1.0f); + kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L); /* indirect light bounce */ if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray)) @@ -897,7 +897,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in PathState ps = state; Ray pray = ray; ShaderData volume_sd; - float3 tp = throughput; + float3 tp = throughput * num_samples_inv; /* branch RNG state */ path_state_branch(&ps, j, num_samples); @@ -909,10 +909,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in if(result == VOLUME_PATH_SCATTERED) { /* todo: support equiangular, MIS and all light sampling. * alternatively get decoupled ray marching working on the GPU */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, tp, &state, &L, num_samples_inv); + kernel_path_volume_connect_light(kg, rng, &volume_sd, tp, &state, &L); if(kernel_path_volume_bounce(kg, rng, &volume_sd, &tp, &ps, &L, &pray)) { - kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L); + kernel_path_indirect(kg, rng, pray, tp, num_samples, ps, &L); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -1047,6 +1047,13 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in ray.P = ray_offset(sd.P, -sd.Ng); ray.t -= sd.ray_length; /* clipping works through transparent */ + +#ifdef __RAY_DIFFERENTIALS__ + ray.dP = sd.dP; + ray.dD.dx = -sd.dI.dx; + ray.dD.dy = -sd.dI.dy; +#endif + #ifdef __VOLUME__ /* enter/exit volume */ kernel_volume_stack_enter_exit(kg, &sd, state.volume_stack); diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h index 9da1cfe7093..da2d5e6eca8 100644 --- a/intern/cycles/kernel/kernel_path_volume.h +++ b/intern/cycles/kernel/kernel_path_volume.h @@ -19,8 +19,7 @@ CCL_NAMESPACE_BEGIN #ifdef __VOLUME_SCATTER__ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng, - ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L, - float num_samples_adjust) + ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L) { #ifdef __EMISSION__ if(!kernel_data.integrator.use_direct_light) @@ -51,7 +50,7 @@ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng, if(!shadow_blocked(kg, state, &light_ray, &shadow)) { /* accumulate */ - path_radiance_accum_light(L, throughput * num_samples_adjust, &L_light, shadow, 1.0f, state->bounce, is_lamp); + path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); } } #endif diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 81306361ea4..1f01622e349 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -254,17 +254,17 @@ enum PathRayFlag { PATH_RAY_SHADOW_TRANSPARENT = 256, PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT), - PATH_RAY_CURVE = 512, /* visibility flag to define curve segments*/ + PATH_RAY_CURVE = 512, /* visibility flag to define curve segments */ + PATH_RAY_VOLUME_SCATTER = 1024, /* volume scattering */ /* note that these can use maximum 12 bits, the other are for layers */ - PATH_RAY_ALL_VISIBILITY = (1|2|4|8|16|32|64|128|256|512), + PATH_RAY_ALL_VISIBILITY = (1|2|4|8|16|32|64|128|256|512|1024), - PATH_RAY_MIS_SKIP = 1024, - PATH_RAY_DIFFUSE_ANCESTOR = 2048, - PATH_RAY_GLOSSY_ANCESTOR = 4096, - PATH_RAY_BSSRDF_ANCESTOR = 8192, - PATH_RAY_SINGLE_PASS_DONE = 16384, - PATH_RAY_VOLUME_SCATTER = 32768, + PATH_RAY_MIS_SKIP = 2048, + PATH_RAY_DIFFUSE_ANCESTOR = 4096, + PATH_RAY_GLOSSY_ANCESTOR = 8192, + PATH_RAY_BSSRDF_ANCESTOR = 16384, + PATH_RAY_SINGLE_PASS_DONE = 32768, /* we need layer member flags to be the 20 upper bits */ PATH_RAY_LAYER_SHIFT = (32-20) @@ -334,21 +334,25 @@ typedef struct PathRadiance { float3 color_glossy; float3 color_transmission; float3 color_subsurface; + float3 color_scatter; float3 direct_diffuse; float3 direct_glossy; float3 direct_transmission; float3 direct_subsurface; + float3 direct_scatter; float3 indirect_diffuse; float3 indirect_glossy; float3 indirect_transmission; float3 indirect_subsurface; + float3 indirect_scatter; float3 path_diffuse; float3 path_glossy; float3 path_transmission; float3 path_subsurface; + float3 path_scatter; float4 shadow; float mist; @@ -362,6 +366,7 @@ typedef struct BsdfEval { float3 transmission; float3 transparent; float3 subsurface; + float3 scatter; } BsdfEval; #else @@ -382,7 +387,8 @@ typedef enum ShaderFlag { SHADER_EXCLUDE_GLOSSY = (1 << 26), SHADER_EXCLUDE_TRANSMIT = (1 << 25), SHADER_EXCLUDE_CAMERA = (1 << 24), - SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT|SHADER_EXCLUDE_CAMERA), + SHADER_EXCLUDE_SCATTER = (1 << 23), + SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT|SHADER_EXCLUDE_CAMERA|SHADER_EXCLUDE_SCATTER), SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY) } ShaderFlag; @@ -522,19 +528,32 @@ typedef enum AttributeStandard { #define MAX_CLOSURE 1 #endif +/* TODO(sergey): This is rather nasty bug happening in here, which + * could be simply a compilers bug for which we can't find a generic + * platform indipendent workaround. Also even if it's a compiler + * issue, it's not so simple to upgrade the compiler in the release + * environment for linux and doing it so closer to the release is + * rather a risky business. + * + * For this release it's probably safer to stick with such a rather + * dirty solution, and look for a cleaner fix during the next release + * cycle. + */ typedef struct ShaderClosure { ClosureType type; float3 weight; - +#ifndef __APPLE__ + float sample_weight; +#endif float data0; float data1; float data2; float3 N; float3 T; - +#ifdef __APPLE__ float sample_weight; - +#endif #ifdef __OSL__ void *prim; #endif @@ -868,7 +887,8 @@ typedef struct KernelIntegrator { int transparent_shadows; /* caustics */ - int no_caustics; + int caustics_reflective; + int caustics_refractive; float filter_glossy; /* seed */ diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 6311be6bfcc..d7789edcfff 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -105,7 +105,7 @@ BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LA CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) -BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, ashikhmin_shirley, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, ashikhmin_shirley, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.N), CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T), CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data0), @@ -124,37 +124,37 @@ BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, glossy_toon, LABEL_GLOSSY) CLOSURE_FLOAT_PARAM(GlossyToonClosure, sc.data1), BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, microfacet_ggx, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.N), CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.T), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, microfacet_beckmann, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.N), CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.T), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY|LABEL_TRANSMIT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data2), BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY|LABEL_TRANSMIT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data2), diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 28135784db9..48498116874 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -164,11 +164,14 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); - /* no caustics option */ - if(scattering == LABEL_GLOSSY && (path_flag & PATH_RAY_DIFFUSE)) { + /* caustic options */ + if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { KernelGlobals *kg = sd->osl_globals; - if(kernel_data.integrator.no_caustics) + + if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { return; + } } /* sample weight */ diff --git a/intern/cycles/kernel/shaders/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h index 447a84255ef..9f10ba8023e 100644 --- a/intern/cycles/kernel/shaders/node_fresnel.h +++ b/intern/cycles/kernel/shaders/node_fresnel.h @@ -34,3 +34,16 @@ float fresnel_dielectric_cos(float cosi, float eta) return result; } +color fresnel_conductor(float cosi, color eta, color k) +{ + color cosi2 = color(cosi*cosi); + color one = color(1, 1, 1); + color tmp_f = eta * eta + k * k; + color tmp = tmp_f * cosi2; + color Rparl2 = (tmp - (2.0 * eta * cosi) + one) / + (tmp + (2.0 * eta * cosi) + one); + color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) / + (tmp_f + (2.0 * eta * cosi) + cosi2); + return (Rparl2 + Rperp2) * 0.5; +} + diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index cd6d9fc53b5..30110db3ef9 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -179,7 +179,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); @@ -207,7 +207,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); @@ -244,8 +244,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && + !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) { break; + } #endif /* index of refraction */ float eta = fmaxf(param2, 1e-5f); @@ -262,12 +264,21 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float sample_weight = sc->sample_weight; sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); - - if(sc) { - sc->N = N; - svm_node_glass_setup(sd, sc, type, eta, roughness, false); +#ifdef __CAUSTICS_TRICKS__ + if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) +#endif + { + if(sc) { + sc->N = N; + svm_node_glass_setup(sd, sc, type, eta, roughness, false); + } } +#ifdef __CAUSTICS_TRICKS__ + if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) + break; +#endif + /* refraction */ sc = &sd->closure[sd->num_closure]; sc->weight = weight; @@ -286,7 +297,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h index 2503912c5c6..b221e0728ec 100644 --- a/intern/cycles/kernel/svm/svm_convert.h +++ b/intern/cycles/kernel/svm/svm_convert.h @@ -45,13 +45,13 @@ ccl_device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint f } case NODE_CONVERT_VF: { float3 f = stack_load_float3(stack, from); - float g = (f.x + f.y + f.z)*(1.0f/3.0f); + float g = average(f); stack_store_float(stack, to, g); break; } case NODE_CONVERT_VI: { float3 f = stack_load_float3(stack, from); - int i = (int)((f.x + f.y + f.z)*(1.0f/3.0f)); + int i = (int)average(f); stack_store_int(stack, to, i); break; } diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp index a877c52fbed..3926ecb99d6 100644 --- a/intern/cycles/render/background.cpp +++ b/intern/cycles/render/background.cpp @@ -78,6 +78,8 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY; if(!(visibility & PATH_RAY_TRANSMIT)) kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT; + if(!(visibility & PATH_RAY_VOLUME_SCATTER)) + kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER; if(!(visibility & PATH_RAY_CAMERA)) kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index c1aefbcfbbc..09973e8bc86 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -80,22 +80,13 @@ void Pass::add(PassType type, vector<Pass>& passes) pass.components = 1; break; case PASS_OBJECT_ID: - pass.components = 1; - pass.filter = false; - break; case PASS_MATERIAL_ID: pass.components = 1; pass.filter = false; break; case PASS_DIFFUSE_COLOR: - pass.components = 4; - break; case PASS_GLOSSY_COLOR: - pass.components = 4; - break; case PASS_TRANSMISSION_COLOR: - pass.components = 4; - break; case PASS_SUBSURFACE_COLOR: pass.components = 4; break; @@ -141,9 +132,6 @@ void Pass::add(PassType type, vector<Pass>& passes) break; case PASS_EMISSION: - pass.components = 4; - pass.exposure = true; - break; case PASS_BACKGROUND: pass.components = 4; pass.exposure = true; diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 32e887d48f1..03a8cd5d2d3 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -43,7 +43,8 @@ Integrator::Integrator() volume_max_steps = 1024; volume_step_size = 0.1f; - no_caustics = false; + caustics_reflective = true; + caustics_refractive = true; filter_glossy = 0.0f; seed = 0; layer_flag = ~0; @@ -91,16 +92,28 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->transparent_max_bounce = transparent_max_bounce + 1; kintegrator->transparent_min_bounce = transparent_min_bounce + 1; - /* At this point kintegrator->transparent_shadows is set automatically - * based on whether shaders use transparent shadows (see shader.cpp). - * If user doesn't want transparent shadows, force them off. */ - if(!transparent_shadows) + /* Transparent Shadows + * We only need to enable transparent shadows, if we actually have + * transparent shaders in the scene. Otherwise we can disable it + * to improve performance a bit. */ + if(transparent_shadows) { + foreach(Shader *shader, scene->shaders) { + /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */ + if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) { + kintegrator->transparent_shadows = true; + break; + } + } + } + else { kintegrator->transparent_shadows = false; + } kintegrator->volume_max_steps = volume_max_steps; kintegrator->volume_step_size = volume_step_size; - kintegrator->no_caustics = no_caustics; + kintegrator->caustics_reflective = caustics_reflective; + kintegrator->caustics_refractive = caustics_refractive; kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy; kintegrator->seed = hash_int(seed); @@ -179,7 +192,8 @@ bool Integrator::modified(const Integrator& integrator) volume_homogeneous_sampling == integrator.volume_homogeneous_sampling && volume_max_steps == integrator.volume_max_steps && volume_step_size == integrator.volume_step_size && - no_caustics == integrator.no_caustics && + caustics_reflective == integrator.caustics_reflective && + caustics_refractive == integrator.caustics_refractive && filter_glossy == integrator.filter_glossy && layer_flag == integrator.layer_flag && seed == integrator.seed && diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index 380c1a65722..13c10e8ca94 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -43,7 +43,8 @@ public: int volume_max_steps; float volume_step_size; - bool no_caustics; + bool caustics_reflective; + bool caustics_refractive; float filter_glossy; int seed; diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 94ab82a600e..1f006637e67 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -121,6 +121,7 @@ Light::Light() use_diffuse = true; use_glossy = true; use_transmission = true; + use_scatter = true; shader = 0; samples = 1; @@ -243,6 +244,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen shader_flag |= SHADER_EXCLUDE_TRANSMIT; use_light_visibility = true; } + if(!(object->visibility & PATH_RAY_VOLUME_SCATTER)) { + shader_flag |= SHADER_EXCLUDE_SCATTER; + use_light_visibility = true; + } for(size_t i = 0; i < mesh->triangles.size(); i++) { Shader *shader = scene->shaders[mesh->shader[i]]; @@ -500,6 +505,10 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce shader_id |= SHADER_EXCLUDE_TRANSMIT; use_light_visibility = true; } + if(!light->use_scatter) { + shader_id |= SHADER_EXCLUDE_SCATTER; + use_light_visibility = true; + } if(light->type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -554,6 +563,10 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce shader_id |= SHADER_EXCLUDE_TRANSMIT; use_light_visibility = true; } + if(!(visibility & PATH_RAY_VOLUME_SCATTER)) { + shader_id |= SHADER_EXCLUDE_SCATTER; + use_light_visibility = true; + } light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 82308cf3e88..89091bb5f9e 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -54,6 +54,7 @@ public: bool use_diffuse; bool use_glossy; bool use_transmission; + bool use_scatter; int shader; int samples; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 927918689f1..d76e511859a 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -325,7 +325,6 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc uint i = 0; bool has_converter_blackbody = false; bool has_volumes = false; - bool has_transparent_shadows = false; foreach(Shader *shader, scene->shaders) { uint flag = 0; @@ -368,10 +367,6 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc shader_flag[i++] = flag; shader_flag[i++] = shader->pass_id; - - /* Check if we need transparent shadows */ - if(flag & SD_HAS_TRANSPARENT_SHADOW) - has_transparent_shadows = true; } device->tex_alloc("__shader_flag", dscene->shader_flag); @@ -402,7 +397,6 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc /* integrator */ KernelIntegrator *kintegrator = &dscene->data.integrator; kintegrator->use_volumes = has_volumes; - kintegrator->transparent_shadows = has_transparent_shadows; } void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene) diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 4ccb5f3e51c..c332e1709db 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -842,7 +842,6 @@ ccl_device_inline float4 max(float4 a, float4 b) ccl_device_inline float4 select(const int4& mask, const float4& a, const float4& b) { #ifdef __KERNEL_SSE__ - /* blendv is sse4, and apparently broken on vs2008 */ return _mm_or_ps(_mm_and_ps(_mm_cvtepi32_ps(mask), a), _mm_andnot_ps(_mm_cvtepi32_ps(mask), b)); /* todo: avoid cvt */ #else return make_float4((mask.x)? a.x: b.x, (mask.y)? a.y: b.y, (mask.z)? a.z: b.z, (mask.w)? a.w: b.w); @@ -1419,10 +1418,14 @@ ccl_device bool map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z) { float len = sqrtf(x * x + y * y + z * z); - if (len > 0.0f) { - if (x == 0.0f && y == 0.0f) *r_u = 0.0f; /* othwise domain error */ - else *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f; - *r_v = 1.0f - safe_acosf(z / len) / (float)M_PI; + if(len > 0.0f) { + if(UNLIKELY(x == 0.0f && y == 0.0f)) { + *r_u = 0.0f; /* othwise domain error */ + } + else { + *r_u = (1.0f - atan2f(x, y) / M_PI_F) / 2.0f; + } + *r_v = 1.0f - safe_acosf(z / len) / M_PI_F; return true; } else { diff --git a/intern/cycles/util/util_stats.h b/intern/cycles/util/util_stats.h index 62b1f1760d7..8758b823084 100644 --- a/intern/cycles/util/util_stats.h +++ b/intern/cycles/util/util_stats.h @@ -30,6 +30,7 @@ public: } void mem_free(size_t size) { + assert(mem_used >= size); mem_used -= size; } |