Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/intersect_closest.h
| Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | ccl_device_forceinline bool integrator_intersect_terminate(KernelGlobals kg, | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| #ifdef __SHADOW_CATCHER__ | #ifdef __SHADOW_CATCHER__ | ||||
| /* Split path if a shadow catcher was hit. */ | /* Split path if a shadow catcher was hit. */ | ||||
| ccl_device_forceinline void integrator_split_shadow_catcher( | ccl_device_forceinline void integrator_split_shadow_catcher( | ||||
| KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect) | KernelGlobals kg, | ||||
| IntegratorState state, | |||||
| ccl_private const Intersection *ccl_restrict isect, | |||||
| ccl_global float *ccl_restrict render_buffer) | |||||
| { | { | ||||
| /* Test if we hit a shadow catcher object, and potentially split the path to continue tracing two | /* Test if we hit a shadow catcher object, and potentially split the path to continue tracing two | ||||
| * paths from here. */ | * paths from here. */ | ||||
| const int object_flags = intersection_get_object_flags(kg, isect); | const int object_flags = intersection_get_object_flags(kg, isect); | ||||
| if (!kernel_shadow_catcher_is_path_split_bounce(kg, state, object_flags)) { | if (!kernel_shadow_catcher_is_path_split_bounce(kg, state, object_flags)) { | ||||
| return; | return; | ||||
| } | } | ||||
| kernel_write_shadow_catcher_bounce_data(kg, state, render_buffer); | |||||
| /* Mark state as having done a shadow catcher split so that it stops contributing to | /* Mark state as having done a shadow catcher split so that it stops contributing to | ||||
| * the shadow catcher matte pass, but keeps contributing to the combined pass. */ | * the shadow catcher matte pass, but keeps contributing to the combined pass. */ | ||||
| INTEGRATOR_STATE_WRITE(state, path, flag) |= PATH_RAY_SHADOW_CATCHER_HIT; | INTEGRATOR_STATE_WRITE(state, path, flag) |= PATH_RAY_SHADOW_CATCHER_HIT; | ||||
| /* Copy current state to new state. */ | /* Copy current state to new state. */ | ||||
| state = integrator_state_shadow_catcher_split(kg, state); | state = integrator_state_shadow_catcher_split(kg, state); | ||||
| /* Initialize new state. | /* Initialize new state. | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | |||||
| * | * | ||||
| * Note that current_kernel is a template value since making this a variable | * Note that current_kernel is a template value since making this a variable | ||||
| * leads to poor performance with CUDA atomics. */ | * leads to poor performance with CUDA atomics. */ | ||||
| template<uint32_t current_kernel> | template<uint32_t current_kernel> | ||||
| ccl_device_forceinline void integrator_intersect_next_kernel( | ccl_device_forceinline void integrator_intersect_next_kernel( | ||||
| KernelGlobals kg, | KernelGlobals kg, | ||||
| IntegratorState state, | IntegratorState state, | ||||
| ccl_private const Intersection *ccl_restrict isect, | ccl_private const Intersection *ccl_restrict isect, | ||||
| ccl_global float *ccl_restrict render_buffer, | |||||
| const bool hit) | const bool hit) | ||||
| { | { | ||||
| /* Continue with volume kernel if we are inside a volume, regardless if we hit anything. */ | /* Continue with volume kernel if we are inside a volume, regardless if we hit anything. */ | ||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| if (!integrator_state_volume_stack_is_empty(kg, state)) { | if (!integrator_state_volume_stack_is_empty(kg, state)) { | ||||
| const bool hit_surface = hit && !(isect->type & PRIMITIVE_LAMP); | const bool hit_surface = hit && !(isect->type & PRIMITIVE_LAMP); | ||||
| const int shader = (hit_surface) ? intersection_get_shader(kg, isect) : SHADER_NONE; | const int shader = (hit_surface) ? intersection_get_shader(kg, isect) : SHADER_NONE; | ||||
| const int flags = (hit_surface) ? kernel_tex_fetch(__shaders, shader).flags : 0; | const int flags = (hit_surface) ? kernel_tex_fetch(__shaders, shader).flags : 0; | ||||
| Show All 26 Lines | else { | ||||
| } | } | ||||
| else { | else { | ||||
| INTEGRATOR_PATH_NEXT_SORTED( | INTEGRATOR_PATH_NEXT_SORTED( | ||||
| current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader); | current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader); | ||||
| } | } | ||||
| #ifdef __SHADOW_CATCHER__ | #ifdef __SHADOW_CATCHER__ | ||||
| /* Handle shadow catcher. */ | /* Handle shadow catcher. */ | ||||
| integrator_split_shadow_catcher(kg, state, isect); | integrator_split_shadow_catcher(kg, state, isect, render_buffer); | ||||
| #endif | #endif | ||||
| } | } | ||||
| else { | else { | ||||
| INTEGRATOR_PATH_TERMINATE(current_kernel); | INTEGRATOR_PATH_TERMINATE(current_kernel); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Nothing hit, continue with background kernel. */ | /* Nothing hit, continue with background kernel. */ | ||||
| INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND); | INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND); | ||||
| } | } | ||||
| } | } | ||||
| /* Schedule next kernel to be executed after shade volume. | /* Schedule next kernel to be executed after shade volume. | ||||
| * | * | ||||
| * The logic here matches integrator_intersect_next_kernel, except that | * The logic here matches integrator_intersect_next_kernel, except that | ||||
| * volume shading and termination testing have already been done. */ | * volume shading and termination testing have already been done. */ | ||||
| template<uint32_t current_kernel> | template<uint32_t current_kernel> | ||||
| ccl_device_forceinline void integrator_intersect_next_kernel_after_volume( | ccl_device_forceinline void integrator_intersect_next_kernel_after_volume( | ||||
| KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect) | KernelGlobals kg, | ||||
| IntegratorState state, | |||||
| ccl_private const Intersection *ccl_restrict isect, | |||||
| ccl_global float *ccl_restrict render_buffer) | |||||
| { | { | ||||
| if (isect->prim != PRIM_NONE) { | if (isect->prim != PRIM_NONE) { | ||||
| /* Hit a surface, continue with light or surface kernel. */ | /* Hit a surface, continue with light or surface kernel. */ | ||||
| if (isect->type & PRIMITIVE_LAMP) { | if (isect->type & PRIMITIVE_LAMP) { | ||||
| INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT); | INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT); | ||||
| return; | return; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Hit a surface, continue with surface kernel unless terminated. */ | /* Hit a surface, continue with surface kernel unless terminated. */ | ||||
| const int shader = intersection_get_shader(kg, isect); | const int shader = intersection_get_shader(kg, isect); | ||||
| const int flags = kernel_tex_fetch(__shaders, shader).flags; | const int flags = kernel_tex_fetch(__shaders, shader).flags; | ||||
| const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE); | const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE); | ||||
| if (use_raytrace_kernel) { | if (use_raytrace_kernel) { | ||||
| INTEGRATOR_PATH_NEXT_SORTED( | INTEGRATOR_PATH_NEXT_SORTED( | ||||
| current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader); | current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader); | ||||
| } | } | ||||
| else { | else { | ||||
| INTEGRATOR_PATH_NEXT_SORTED( | INTEGRATOR_PATH_NEXT_SORTED( | ||||
| current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader); | current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader); | ||||
| } | } | ||||
| #ifdef __SHADOW_CATCHER__ | #ifdef __SHADOW_CATCHER__ | ||||
| /* Handle shadow catcher. */ | /* Handle shadow catcher. */ | ||||
| integrator_split_shadow_catcher(kg, state, isect); | integrator_split_shadow_catcher(kg, state, isect, render_buffer); | ||||
| #endif | #endif | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Nothing hit, continue with background kernel. */ | /* Nothing hit, continue with background kernel. */ | ||||
| INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND); | INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND); | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| ccl_device void integrator_intersect_closest(KernelGlobals kg, IntegratorState state) | ccl_device void integrator_intersect_closest(KernelGlobals kg, | ||||
| IntegratorState state, | |||||
| ccl_global float *ccl_restrict render_buffer) | |||||
| { | { | ||||
| PROFILING_INIT(kg, PROFILING_INTERSECT_CLOSEST); | PROFILING_INIT(kg, PROFILING_INTERSECT_CLOSEST); | ||||
| /* Read ray from integrator state into local memory. */ | /* Read ray from integrator state into local memory. */ | ||||
| Ray ray ccl_optional_struct_init; | Ray ray ccl_optional_struct_init; | ||||
| integrator_state_read_ray(kg, state, &ray); | integrator_state_read_ray(kg, state, &ray); | ||||
| kernel_assert(ray.t != 0.0f); | kernel_assert(ray.t != 0.0f); | ||||
| Show All 34 Lines | hit = lights_intersect( | ||||
| hit; | hit; | ||||
| } | } | ||||
| /* Write intersection result into global integrator state memory. */ | /* Write intersection result into global integrator state memory. */ | ||||
| integrator_state_write_isect(kg, state, &isect); | integrator_state_write_isect(kg, state, &isect); | ||||
| /* Setup up next kernel to be executed. */ | /* Setup up next kernel to be executed. */ | ||||
| integrator_intersect_next_kernel<DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST>( | integrator_intersect_next_kernel<DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST>( | ||||
| kg, state, &isect, hit); | kg, state, &isect, render_buffer, hit); | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||