forked from bartvdbraak/blender
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!
This commit is contained in:
parent
4d85396fe4
commit
f01e43fac3
@ -84,7 +84,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
|
||||
light_ray.dP = sd->dP;
|
||||
light_ray.dD = differential3_zero();
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
|
||||
path_radiance_accum_ao(L, state, throughput, ao_alpha, ao_bsdf, ao_shadow);
|
||||
}
|
||||
else {
|
||||
|
@ -54,7 +54,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
|
||||
light_ray.dP = sd->dP;
|
||||
light_ray.dD = differential3_zero();
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
|
||||
path_radiance_accum_ao(L, state, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow);
|
||||
}
|
||||
else {
|
||||
|
@ -67,7 +67,7 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
|
||||
}
|
||||
@ -104,7 +104,7 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
|
||||
}
|
||||
@ -130,7 +130,7 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, is_lamp);
|
||||
}
|
||||
@ -257,7 +257,7 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg,
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ ccl_device_inline void kernel_path_volume_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
|
||||
}
|
||||
@ -179,7 +179,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, tp*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
|
||||
}
|
||||
@ -228,7 +228,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, tp*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
|
||||
}
|
||||
@ -266,7 +266,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
|
||||
/* trace shadow ray */
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
|
||||
if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
|
||||
/* accumulate */
|
||||
path_radiance_accum_light(L, state, tp, &L_light, shadow, 1.0f, is_lamp);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -89,6 +89,7 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
|
||||
float3 shadow;
|
||||
|
||||
if(!shadow_blocked(kg,
|
||||
sd,
|
||||
emission_sd,
|
||||
state,
|
||||
&ray,
|
||||
|
Loading…
Reference in New Issue
Block a user