diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-07 22:59:23 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-07 22:59:23 +0400 |
commit | 58a290234b0719ce48854e2f6744575b353bf7d3 (patch) | |
tree | 8891bc5663c9b8e19cdaa2a1d58ec0e39ff3f2f3 /intern/cycles/kernel | |
parent | b20a7e01d046b95a79663da1a8072358709a5a8b (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/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/kernel_accumulate.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 28 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 6 |
4 files changed, 33 insertions, 9 deletions
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 */ |