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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-08-02 00:40:38 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-08-07 18:54:26 +0300
commitfc38276d74e1d451663c70f82e7f54293d24bbe4 (patch)
treedb1e8826e2ea74bab3a0029b4ffb078d38154e36 /intern/cycles/kernel/kernel_shadow.h
parentdc4d850d109f64bc0c56b53b9a50a8e9c70951fa (diff)
Fix Cycles shadow catcher objects influencing each other.
Since all the shadow catchers are already assumed to be in the footage, the shadows they cast on each other are already in the footage too. So don't just let shadow catchers skip self, but all shadow catchers. Another justification is that it should not matter if the shadow catcher is modeled as one object or multiple separate objects, the resulting render should be the same. Differential Revision: https://developer.blender.org/D2763
Diffstat (limited to 'intern/cycles/kernel/kernel_shadow.h')
-rw-r--r--intern/cycles/kernel/kernel_shadow.h84
1 files changed, 30 insertions, 54 deletions
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index fab5946970d..10e9083551e 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -72,13 +72,14 @@ ccl_device_forceinline bool shadow_handle_transparent_isect(
ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
+ const uint visibility,
Ray *ray,
Intersection *isect,
float3 *shadow)
{
const bool blocked = scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_OPAQUE,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
isect,
NULL,
0.0f, 0.0f);
@@ -128,7 +129,7 @@ ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *hits,
uint max_hits,
@@ -141,7 +142,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
const bool blocked = scene_intersect_shadow_all(kg,
ray,
hits,
- skip_object,
+ visibility,
max_hits,
&num_hits);
/* If no opaque surface found but we did find transparent hits,
@@ -218,7 +219,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
uint max_hits,
float3 *shadow)
@@ -253,7 +254,7 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
return shadow_blocked_transparent_all_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
hits,
max_hits,
@@ -278,14 +279,14 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *isect,
const bool blocked,
const bool is_transparent_isect,
float3 *shadow)
{
- if((blocked && is_transparent_isect) || skip_object != OBJECT_NONE) {
+ if(blocked && is_transparent_isect) {
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
float3 Pend = ray->P + ray->D*ray->t;
int bounce = state->transparent_bounce;
@@ -304,30 +305,13 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
}
if(!scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_TRANSPARENT,
+ visibility & PATH_RAY_SHADOW_TRANSPARENT,
isect,
NULL,
0.0f, 0.0f))
{
break;
}
-#ifdef __SHADOW_TRICKS__
- if(skip_object != OBJECT_NONE) {
- const int isect_object = (isect->object == PRIM_NONE)
- ? kernel_tex_fetch(__prim_object, isect->prim)
- : isect->object;
- if(isect_object == skip_object) {
- shader_setup_from_ray(kg, shadow_sd, isect, ray);
- /* Move ray forward. */
- ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng);
- if(ray->t != FLT_MAX) {
- ray->D = normalize_len(Pend - ray->P, &ray->t);
- }
- bounce++;
- continue;
- }
- }
-#endif
if(!shader_transparent_shadow(kg, isect)) {
return true;
}
@@ -373,31 +357,24 @@ ccl_device bool shadow_blocked_transparent_stepped(
KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *isect,
float3 *shadow)
{
- bool blocked, is_transparent_isect;
- if(skip_object == OBJECT_NONE) {
- blocked = scene_intersect(kg,
- *ray,
- PATH_RAY_SHADOW_OPAQUE,
- isect,
- NULL,
- 0.0f, 0.0f);
- is_transparent_isect = blocked
- ? shader_transparent_shadow(kg, isect)
- : false;
- }
- else {
- blocked = false;
- is_transparent_isect = false;
- }
+ bool blocked = scene_intersect(kg,
+ *ray,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
+ isect,
+ NULL,
+ 0.0f, 0.0f);
+ bool is_transparent_isect = blocked
+ ? shader_transparent_shadow(kg, isect)
+ : false;
return shadow_blocked_transparent_stepped_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
isect,
blocked,
@@ -422,25 +399,24 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return false;
}
#ifdef __SHADOW_TRICKS__
- const int skip_object = state->catcher_object;
+ const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER)
+ ? PATH_RAY_SHADOW_NON_CATCHER
+ : PATH_RAY_SHADOW;
#else
- const int skip_object = OBJECT_NONE;
+ const uint visibility = PATH_RAY_SHADOW;
#endif
/* Do actual shadow shading. */
/* First of all, we check if integrator requires transparent shadows.
* if not, we use simplest and fastest ever way to calculate occlusion.
- *
- * NOTE: We can't do quick opaque test here if we are on shadow-catcher
- * path because we don't want catcher object to be casting shadow here.
*/
#ifdef __TRANSPARENT_SHADOWS__
- if(!kernel_data.integrator.transparent_shadows &&
- skip_object == OBJECT_NONE)
+ if(!kernel_data.integrator.transparent_shadows)
#endif
{
return shadow_blocked_opaque(kg,
shadow_sd,
state,
+ visibility,
ray,
&isect,
shadow);
@@ -467,7 +443,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
*/
const bool blocked = scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_OPAQUE,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
&isect,
NULL,
0.0f, 0.0f);
@@ -480,7 +456,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_stepped_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
&isect,
blocked,
@@ -491,7 +467,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_all(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
max_hits,
shadow);
@@ -500,7 +476,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_stepped(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
&isect,
shadow);