Fix shadow catcher behind transparent object on GPU
The assumption about absent shadow path was wrong. The rest of the changes are to ensure shadow paths are finished prior to the split, so that they write to the proper passes. The issue was caught by running regression tests on OptiX. Differential Revision: https://developer.blender.org/D12857
This commit is contained in:
parent
4f5ef3b018
commit
aa46459543
Notes:
blender-bot
2023-02-14 11:20:29 +01:00
Referenced by issue #92213, Blender 3.0 - rendering with shadow catcher is giving error message "Illegal address in CUDA queue copy_from_device (integrator_shade_surface_raytrace integrator_sorted_paths_array prefix_sum)"
|
@ -342,10 +342,14 @@ bool PathTraceWorkGPU::enqueue_path_iteration()
|
|||
}
|
||||
|
||||
/* Finish shadows before potentially adding more shadow rays. We can only
|
||||
* store one shadow ray in the integrator state. */
|
||||
* store one shadow ray in the integrator state.
|
||||
*
|
||||
* When there is a shadow catcher in the scene finish shadow rays before invoking interesect
|
||||
* closest kernel since so that the shadow paths are writing to the pre-split state. */
|
||||
if (kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE ||
|
||||
kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
|
||||
kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME) {
|
||||
kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME ||
|
||||
(has_shadow_catcher() && kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST)) {
|
||||
if (queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW]) {
|
||||
enqueue_path_iteration(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
|
||||
return true;
|
||||
|
|
|
@ -126,12 +126,7 @@ ccl_device_forceinline void integrator_intersect_shader_next_kernel(
|
|||
if (kernel_data.film.pass_background != PASS_UNUSED && !kernel_data.background.transparent) {
|
||||
INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_SHADOW_CATCHER_BACKGROUND;
|
||||
|
||||
if (use_raytrace_kernel) {
|
||||
INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
|
||||
}
|
||||
else {
|
||||
INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
|
||||
}
|
||||
INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
|
||||
}
|
||||
else if (use_raytrace_kernel) {
|
||||
INTEGRATOR_PATH_INIT_SORTED(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader);
|
||||
|
@ -139,6 +134,13 @@ ccl_device_forceinline void integrator_intersect_shader_next_kernel(
|
|||
else {
|
||||
INTEGRATOR_PATH_INIT_SORTED(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader);
|
||||
}
|
||||
|
||||
/* If the split happened after bounce through a transparent object it's possible to have shadow
|
||||
* patch. Make sure it is properly re-scheduled on the split path. */
|
||||
const int shadow_kernel = INTEGRATOR_STATE(shadow_path, queued_kernel);
|
||||
if (shadow_kernel != 0) {
|
||||
INTEGRATOR_SHADOW_PATH_INIT(shadow_kernel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -262,12 +262,6 @@ ccl_device_inline void integrator_state_shadow_catcher_split(INTEGRATOR_STATE_AR
|
|||
integrator_state_copy_only(to_state, state);
|
||||
|
||||
kernel_integrator_state.path.flag[to_state] |= PATH_RAY_SHADOW_CATCHER_PASS;
|
||||
|
||||
/* Sanity check: expect to split in the intersect-closest kernel, where there is no shadow ray
|
||||
* and no sorting yet. */
|
||||
kernel_assert(INTEGRATOR_STATE(shadow_path, queued_kernel) == 0);
|
||||
kernel_assert(kernel_integrator_state.sort_key_counter[INTEGRATOR_STATE(path, queued_kernel)] ==
|
||||
nullptr);
|
||||
#else
|
||||
|
||||
IntegratorStateCPU *ccl_restrict split_state = state + 1;
|
||||
|
|
Loading…
Reference in New Issue