Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/app/cycles_xml.cpp3
-rw-r--r--intern/cycles/blender/addon/presets.py16
-rw-r--r--intern/cycles/blender/addon/properties.py20
-rw-r--r--intern/cycles/blender/addon/ui.py5
-rw-r--r--intern/cycles/blender/addon/version_update.py9
-rw-r--r--intern/cycles/blender/blender_object.cpp2
-rw-r--r--intern/cycles/blender/blender_shader.cpp1
-rw-r--r--intern/cycles/blender/blender_sync.cpp3
-rw-r--r--intern/cycles/device/device_cpu.cpp24
-rw-r--r--intern/cycles/device/device_cuda.cpp14
-rw-r--r--intern/cycles/device/device_memory.h2
-rw-r--r--intern/cycles/device/device_opencl.cpp4
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h18
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h47
-rw-r--r--intern/cycles/kernel/kernel_emission.h8
-rw-r--r--intern/cycles/kernel/kernel_path.h17
-rw-r--r--intern/cycles/kernel/kernel_path_volume.h5
-rw-r--r--intern/cycles/kernel/kernel_types.h46
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp14
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp9
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.h13
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h27
-rw-r--r--intern/cycles/kernel/svm/svm_convert.h4
-rw-r--r--intern/cycles/render/background.cpp2
-rw-r--r--intern/cycles/render/film.cpp12
-rw-r--r--intern/cycles/render/integrator.cpp28
-rw-r--r--intern/cycles/render/integrator.h3
-rw-r--r--intern/cycles/render/light.cpp13
-rw-r--r--intern/cycles/render/light.h1
-rw-r--r--intern/cycles/render/shader.cpp6
-rw-r--r--intern/cycles/util/util_math.h13
-rw-r--r--intern/cycles/util/util_stats.h1
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;
}