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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-06-07 22:59:23 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-06-07 22:59:23 +0400
commit58a290234b0719ce48854e2f6744575b353bf7d3 (patch)
tree8891bc5663c9b8e19cdaa2a1d58ec0e39ff3f2f3 /intern
parentb20a7e01d046b95a79663da1a8072358709a5a8b (diff)
Cycles: ray visibility options now work for lamps and mesh lights, with and without
multiple importance sampling, so you can disable them for diffuse/glossy/transmission. The Light Path node here is still weak and does not give this info. To make that work we'd need to evaluate the shader multiple times which is slow and we can't detect well enough when it is actually needed.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/addon/ui.py2
-rw-r--r--intern/cycles/blender/blender_object.cpp6
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h3
-rw-r--r--intern/cycles/kernel/kernel_emission.h28
-rw-r--r--intern/cycles/kernel/kernel_light.h5
-rw-r--r--intern/cycles/kernel/kernel_types.h6
-rw-r--r--intern/cycles/render/film.cpp4
-rw-r--r--intern/cycles/render/film.h2
-rw-r--r--intern/cycles/render/light.cpp38
-rw-r--r--intern/cycles/render/light.h3
10 files changed, 83 insertions, 14 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index b35bdf8f511..8950b4f83c4 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -528,7 +528,7 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
- return CyclesButtonsPanel.poll(context) and ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META'} # todo: 'LAMP'
+ return CyclesButtonsPanel.poll(context) and ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'}
def draw(self, context):
layout = self.layout
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 5dbb46bda2e..75f0c48a8a2 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -159,6 +159,12 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
light->samples = get_int(clamp, "samples");
+ /* visibility */
+ uint visibility = object_ray_visibility(b_ob);
+ light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
+ light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
+ light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
+
/* tag */
light->tag_update(scene);
}
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 557990d7220..e6307f23b32 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -232,12 +232,9 @@ __device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughpu
L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
if(is_lamp) {
- float3 sum = throughput*(bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission);
-
L->shadow.x += shadow.x*shadow_fac;
L->shadow.y += shadow.y*shadow_fac;
L->shadow.z += shadow.z*shadow_fac;
- L->shadow.w += average(sum);
}
}
else {
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 74f768c899c..869c8539809 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -102,8 +102,6 @@ __device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int li
if(is_zero(light_eval))
return false;
- /* todo: use visibility flag to skip lights */
-
/* evaluate BSDF at shading point */
float bsdf_pdf;
@@ -117,6 +115,18 @@ __device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int li
bsdf_eval_mul(eval, light_eval/ls.pdf);
+#ifdef __PASSES__
+ /* use visibility flag to skip lights */
+ if(ls.shader & SHADER_EXCLUDE_ANY) {
+ if(ls.shader & SHADER_EXCLUDE_DIFFUSE)
+ eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ if(ls.shader & SHADER_EXCLUDE_GLOSSY)
+ 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);
+ }
+#endif
+
if(bsdf_eval_is_zero(eval))
return false;
@@ -185,7 +195,19 @@ __device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int p
if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
return false;
-
+
+#ifdef __PASSES__
+ /* use visibility flag to skip lights */
+ if(ls.shader & SHADER_EXCLUDE_ANY) {
+ if((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE))
+ return false;
+ if((ls.shader & SHADER_EXCLUDE_GLOSSY) && (path_flag & PATH_RAY_GLOSSY))
+ return false;
+ if((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT))
+ return false;
+ }
+#endif
+
/* todo: missing texture coordinates */
float u = 0.0f;
float v = 0.0f;
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 9f198c6c595..4983122fb34 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -558,11 +558,11 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
if(prim >= 0) {
int object = __float_as_int(l.w);
#ifdef __HAIR__
- int segment = __float_as_int(l.z);
+ int segment = __float_as_int(l.z) & SHADER_MASK;
#endif
#ifdef __HAIR__
- if (segment != (int)~0)
+ if (segment != SHADER_MASK)
curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
else
#endif
@@ -571,6 +571,7 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
/* compute incoming direction, distance and pdf */
ls->D = normalize_len(ls->P - P, &ls->t);
ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->shader |= __float_as_int(l.z) & (~SHADER_MASK);
}
else {
int lamp = -prim-1;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index abdb609b55f..11cdad6bb44 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -326,8 +326,12 @@ typedef enum ShaderFlag {
SHADER_CAST_SHADOW = (1 << 30),
SHADER_AREA_LIGHT = (1 << 29),
SHADER_USE_MIS = (1 << 28),
+ SHADER_EXCLUDE_DIFFUSE = (1 << 27),
+ SHADER_EXCLUDE_GLOSSY = (1 << 26),
+ SHADER_EXCLUDE_TRANSMIT = (1 << 25),
+ SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT),
- SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS)
+ SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY)
} ShaderFlag;
/* Light Type */
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 1fe30376adc..43aef755ba3 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -259,6 +259,8 @@ Film::Film()
mist_depth = 100.0f;
mist_falloff = 1.0f;
+ use_light_visibility = false;
+
need_update = true;
}
@@ -279,7 +281,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->exposure = exposure;
kfilm->pass_flag = 0;
kfilm->pass_stride = 0;
- kfilm->use_light_pass = 0;
+ kfilm->use_light_pass = use_light_visibility;
foreach(Pass& pass, passes) {
kfilm->pass_flag |= pass.type;
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 1df0e95a48a..0147306c1e3 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -61,6 +61,8 @@ public:
float mist_depth;
float mist_falloff;
+ bool use_light_visibility;
+
bool need_update;
Film();
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 1d2acf79b6c..71e1f57eb36 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -18,6 +18,7 @@
#include "device.h"
#include "integrator.h"
+#include "film.h"
#include "light.h"
#include "mesh.h"
#include "object.h"
@@ -116,6 +117,9 @@ Light::Light()
cast_shadow = true;
use_mis = false;
+ use_diffuse = true;
+ use_glossy = true;
+ use_transmission = true;
shader = 0;
samples = 1;
@@ -221,17 +225,31 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
bool transform_applied = mesh->transform_applied;
Transform tfm = object->tfm;
int object_id = j;
+ int shader_id = SHADER_MASK;
if(transform_applied)
object_id = ~object_id;
+ if(!(object->visibility & PATH_RAY_DIFFUSE)) {
+ shader_id |= SHADER_EXCLUDE_DIFFUSE;
+ scene->film->use_light_visibility = true;
+ }
+ if(!(object->visibility & PATH_RAY_GLOSSY)) {
+ shader_id |= SHADER_EXCLUDE_GLOSSY;
+ scene->film->use_light_visibility = true;
+ }
+ if(!(object->visibility & PATH_RAY_TRANSMIT)) {
+ shader_id |= SHADER_EXCLUDE_TRANSMIT;
+ scene->film->use_light_visibility = true;
+ }
+
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Shader *shader = scene->shaders[mesh->shader[i]];
if(shader->sample_as_light && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
- distribution[offset].z = __int_as_float(~0);
+ distribution[offset].z = __int_as_float(shader_id);
distribution[offset].w = __int_as_float(object_id);
offset++;
@@ -250,7 +268,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
}
- /*sample as light disabled for strands*/
+ /* sample as light disabled for strands */
#if 0
size_t i = 0;
@@ -262,7 +280,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
for(int j = 0; j < curve.num_segments(); j++) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
- distribution[offset].z = __int_as_float(j);
+ distribution[offset].z = __int_as_float(j) & SHADER_MASK;
distribution[offset].w = __int_as_float(object_id);
offset++;
@@ -493,6 +511,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
}
}
}
+ scene->film->use_light_visibility = false;
for(size_t i = 0; i < scene->lights.size(); i++) {
Light *light = scene->lights[i];
@@ -504,6 +523,19 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
if(!light->cast_shadow)
shader_id &= ~SHADER_CAST_SHADOW;
+ if(!light->use_diffuse) {
+ shader_id |= SHADER_EXCLUDE_DIFFUSE;
+ scene->film->use_light_visibility = true;
+ }
+ if(!light->use_glossy) {
+ shader_id |= SHADER_EXCLUDE_GLOSSY;
+ scene->film->use_light_visibility = true;
+ }
+ if(!light->use_transmission) {
+ shader_id |= SHADER_EXCLUDE_TRANSMIT;
+ scene->film->use_light_visibility = true;
+ }
+
if(light->type == LIGHT_POINT) {
shader_id &= ~SHADER_AREA_LIGHT;
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index acd1692a41f..0e833fdea1d 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -53,6 +53,9 @@ public:
bool cast_shadow;
bool use_mis;
+ bool use_diffuse;
+ bool use_glossy;
+ bool use_transmission;
int shader;
int samples;