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:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-09-05 16:38:11 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-09-05 16:48:34 +0300
commitf01e43fac392155b02ae819c466db8bac3826016 (patch)
treecc9325ede867cf41160ef8828f7641c4ca7bbdac /intern/cycles/kernel/kernel_shadow.h
parent4d85396fe4f7e3a870fb844b5207179f7dd03eb2 (diff)
Fix T52433: Volume Absorption color tint
Need to exit the volume stack when shadow ray laves the medium. Thanks Brecht for review and help in troubleshooting!
Diffstat (limited to 'intern/cycles/kernel/kernel_shadow.h')
-rw-r--r--intern/cycles/kernel/kernel_shadow.h84
1 files changed, 68 insertions, 16 deletions
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index bb6bdc7fbd0..b409aca7674 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -119,12 +119,46 @@ ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
# define SHADOW_STACK_MAX_HITS 64
+# ifdef __VOLUME__
+struct VolumeState {
+# ifdef __SPLIT_KERNEL__
+# else
+ PathState ps;
+# endif
+};
+
+/* Get PathState ready for use for volume stack evaluation. */
+ccl_device_inline PathState *shadow_blocked_volume_path_state(
+ KernelGlobals *kg,
+ VolumeState *volume_state,
+ ccl_addr_space PathState *state,
+ ShaderData *sd,
+ Ray *ray)
+{
+# ifdef __SPLIT_KERNEL__
+ ccl_addr_space PathState *ps =
+ &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
+# else
+ PathState *ps = &volume_state->ps;
+# endif
+ *ps = *state;
+ /* We are checking for shadow on the "other" side of the surface, so need
+ * to discard volume we are currently at.
+ */
+ if(dot(sd->Ng, ray->D) < 0.0f) {
+ kernel_volume_stack_enter_exit(kg, sd, ps->volume_stack);
+ }
+ return ps;
+}
+#endif // __VOLUME__
+
/* Actual logic with traversal loop implementation which is free from device
* specific tweaks.
*
* Note that hits array should be as big as max_hits+1.
*/
ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
+ ShaderData *sd,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
const uint visibility,
@@ -143,6 +177,9 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
visibility,
max_hits,
&num_hits);
+# ifdef __VOLUME__
+ VolumeState volume_state;
+# endif
/* If no opaque surface found but we did find transparent hits,
* shade them.
*/
@@ -153,13 +190,11 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
int bounce = state->transparent_bounce;
Intersection *isect = hits;
# ifdef __VOLUME__
-# ifdef __SPLIT_KERNEL__
- ccl_addr_space PathState *ps = &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
-# else
- PathState ps_object;
- PathState *ps = &ps_object;
-# endif
- *ps = *state;
+ PathState *ps = shadow_blocked_volume_path_state(kg,
+ &volume_state,
+ state,
+ sd,
+ ray);
# endif
sort_intersections(hits, num_hits);
for(int hit = 0; hit < num_hits; hit++, isect++) {
@@ -205,7 +240,12 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
# ifdef __VOLUME__
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
/* Apply attenuation from current volume shader. */
- kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
+ PathState *ps = shadow_blocked_volume_path_state(kg,
+ &volume_state,
+ state,
+ sd,
+ ray);
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
}
# endif
return blocked;
@@ -215,6 +255,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
* loop to help readability of the actual logic.
*/
ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
+ ShaderData *sd,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
const uint visibility,
@@ -250,6 +291,7 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
# endif /* __KERNEL_GPU__ */
/* Invoke actual traversal. */
return shadow_blocked_transparent_all_loop(kg,
+ sd,
shadow_sd,
state,
visibility,
@@ -275,6 +317,7 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
*/
ccl_device bool shadow_blocked_transparent_stepped_loop(
KernelGlobals *kg,
+ ShaderData *sd,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
const uint visibility,
@@ -284,18 +327,18 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
const bool is_transparent_isect,
float3 *shadow)
{
+# ifdef __VOLUME__
+ VolumeState volume_state;
+# endif
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;
# ifdef __VOLUME__
-# ifdef __SPLIT_KERNEL__
- ccl_addr_space PathState *ps = &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
-# else
- PathState ps_object;
- PathState *ps = &ps_object;
-# endif
- *ps = *state;
+ PathState *ps = shadow_blocked_volume_path_state(kg,
+ &volume_state,
+ state,
+ sd);
# endif
for(;;) {
if(bounce >= kernel_data.integrator.transparent_max_bounce) {
@@ -345,7 +388,11 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
# ifdef __VOLUME__
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
/* Apply attenuation from current volume shader. */
- kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
+ PathState *ps = shadow_blocked_volume_path_state(kg,
+ &volume_state,
+ state,
+ sd);
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
}
# endif
return blocked;
@@ -353,6 +400,7 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
ccl_device bool shadow_blocked_transparent_stepped(
KernelGlobals *kg,
+ ShaderData *sd,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
const uint visibility,
@@ -370,6 +418,7 @@ ccl_device bool shadow_blocked_transparent_stepped(
? shader_transparent_shadow(kg, isect)
: false;
return shadow_blocked_transparent_stepped_loop(kg,
+ sd,
shadow_sd,
state,
visibility,
@@ -384,6 +433,7 @@ ccl_device bool shadow_blocked_transparent_stepped(
#endif /* __TRANSPARENT_SHADOWS__ */
ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
+ ShaderData *sd,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
Ray *ray_input,
@@ -452,6 +502,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
max_hits + 1 >= SHADOW_STACK_MAX_HITS)
{
return shadow_blocked_transparent_stepped_loop(kg,
+ sd,
shadow_sd,
state,
visibility,
@@ -463,6 +514,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
}
# endif /* __KERNEL_GPU__ */
return shadow_blocked_transparent_all(kg,
+ sd,
shadow_sd,
state,
visibility,