Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/intersect_volume_stack.h
| Show All 36 Lines | ccl_device void integrator_volume_stack_update_for_subsurface(KernelGlobals kg, | ||||
| Ray volume_ray ccl_optional_struct_init; | Ray volume_ray ccl_optional_struct_init; | ||||
| volume_ray.P = from_P; | volume_ray.P = from_P; | ||||
| volume_ray.D = normalize_len(to_P - from_P, &volume_ray.t); | volume_ray.D = normalize_len(to_P - from_P, &volume_ray.t); | ||||
| /* Store to avoid global fetches on every intersection step. */ | /* Store to avoid global fetches on every intersection step. */ | ||||
| const uint volume_stack_size = kernel_data.volume_stack_size; | const uint volume_stack_size = kernel_data.volume_stack_size; | ||||
| const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | |||||
| const uint32_t visibility = SHADOW_CATCHER_PATH_VISIBILITY(path_flag, PATH_RAY_ALL_VISIBILITY); | |||||
| #ifdef __VOLUME_RECORD_ALL__ | #ifdef __VOLUME_RECORD_ALL__ | ||||
| Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | ||||
| uint num_hits = scene_intersect_volume_all( | uint num_hits = scene_intersect_volume_all( | ||||
| kg, &volume_ray, hits, 2 * volume_stack_size, PATH_RAY_ALL_VISIBILITY); | kg, &volume_ray, hits, 2 * volume_stack_size, visibility); | ||||
| if (num_hits > 0) { | if (num_hits > 0) { | ||||
| Intersection *isect = hits; | Intersection *isect = hits; | ||||
| qsort(hits, num_hits, sizeof(Intersection), intersections_compare); | qsort(hits, num_hits, sizeof(Intersection), intersections_compare); | ||||
| for (uint hit = 0; hit < num_hits; ++hit, ++isect) { | for (uint hit = 0; hit < num_hits; ++hit, ++isect) { | ||||
| shader_setup_from_ray(kg, stack_sd, &volume_ray, isect); | shader_setup_from_ray(kg, stack_sd, &volume_ray, isect); | ||||
| volume_stack_enter_exit(kg, state, stack_sd); | volume_stack_enter_exit(kg, state, stack_sd); | ||||
| } | } | ||||
| } | } | ||||
| #else | #else | ||||
| Intersection isect; | Intersection isect; | ||||
| int step = 0; | int step = 0; | ||||
| while (step < 2 * volume_stack_size && | while (step < 2 * volume_stack_size && | ||||
| scene_intersect_volume(kg, &volume_ray, &isect, PATH_RAY_ALL_VISIBILITY)) { | scene_intersect_volume(kg, &volume_ray, &isect, visibility)) { | ||||
| shader_setup_from_ray(kg, stack_sd, &volume_ray, &isect); | shader_setup_from_ray(kg, stack_sd, &volume_ray, &isect); | ||||
| volume_stack_enter_exit(kg, state, stack_sd); | volume_stack_enter_exit(kg, state, stack_sd); | ||||
| /* Move ray forward. */ | /* Move ray forward. */ | ||||
| volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); | volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); | ||||
| if (volume_ray.t != FLT_MAX) { | if (volume_ray.t != FLT_MAX) { | ||||
| volume_ray.D = normalize_len(to_P - volume_ray.P, &volume_ray.t); | volume_ray.D = normalize_len(to_P - volume_ray.P, &volume_ray.t); | ||||
| } | } | ||||
| ++step; | ++step; | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| ccl_device void integrator_intersect_volume_stack(KernelGlobals kg, IntegratorState state) | ccl_device void integrator_volume_stack_init(KernelGlobals kg, IntegratorState state) | ||||
| { | { | ||||
| PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_STACK); | PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_STACK); | ||||
| ShaderDataTinyStorage stack_sd_storage; | ShaderDataTinyStorage stack_sd_storage; | ||||
| ccl_private ShaderData *stack_sd = AS_SHADER_DATA(&stack_sd_storage); | ccl_private ShaderData *stack_sd = AS_SHADER_DATA(&stack_sd_storage); | ||||
| Ray volume_ray ccl_optional_struct_init; | Ray volume_ray ccl_optional_struct_init; | ||||
| integrator_state_read_ray(kg, state, &volume_ray); | integrator_state_read_ray(kg, state, &volume_ray); | ||||
| volume_ray.t = FLT_MAX; | volume_ray.t = FLT_MAX; | ||||
| const uint visibility = (INTEGRATOR_STATE(state, path, flag) & PATH_RAY_ALL_VISIBILITY); | |||||
| int stack_index = 0, enclosed_index = 0; | int stack_index = 0, enclosed_index = 0; | ||||
| /* Write background shader. */ | /* Initialize volume stack. */ | ||||
| INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 0, object) = OBJECT_NONE; | |||||
| INTEGRATOR_STATE_ARRAY_WRITE( | |||||
| state, volume_stack, 0, shader) = kernel_data.background.volume_shader; | |||||
| INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 1, object) = OBJECT_NONE; | |||||
| INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 1, shader) = SHADER_NONE; | |||||
| /* Increment for background shader. */ | |||||
| if (kernel_data.background.volume_shader != SHADER_NONE) { | if (kernel_data.background.volume_shader != SHADER_NONE) { | ||||
| const VolumeStack new_entry = {OBJECT_NONE, kernel_data.background.volume_shader}; | |||||
| integrator_state_write_volume_stack(state, stack_index, new_entry); | |||||
| stack_index++; | stack_index++; | ||||
| } | } | ||||
| /* Store to avoid global fetches on every intersection step. */ | /* Store to avoid global fetches on every intersection step. */ | ||||
| const uint volume_stack_size = kernel_data.volume_stack_size; | const uint volume_stack_size = kernel_data.volume_stack_size; | ||||
| const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | |||||
| const uint32_t visibility = SHADOW_CATCHER_PATH_VISIBILITY(path_flag, PATH_RAY_CAMERA); | |||||
| #ifdef __VOLUME_RECORD_ALL__ | #ifdef __VOLUME_RECORD_ALL__ | ||||
| Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | ||||
| uint num_hits = scene_intersect_volume_all( | uint num_hits = scene_intersect_volume_all( | ||||
| kg, &volume_ray, hits, 2 * volume_stack_size, visibility); | kg, &volume_ray, hits, 2 * volume_stack_size, visibility); | ||||
| if (num_hits > 0) { | if (num_hits > 0) { | ||||
| int enclosed_volumes[MAX_VOLUME_STACK_SIZE]; | int enclosed_volumes[MAX_VOLUME_STACK_SIZE]; | ||||
| Intersection *isect = hits; | Intersection *isect = hits; | ||||
| ▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | while (stack_index < volume_stack_size - 1 && enclosed_index < volume_stack_size - 1 && | ||||
| volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); | volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); | ||||
| ++step; | ++step; | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* Write terminator. */ | /* Write terminator. */ | ||||
| const VolumeStack new_entry = {OBJECT_NONE, SHADER_NONE}; | const VolumeStack new_entry = {OBJECT_NONE, SHADER_NONE}; | ||||
| integrator_state_write_volume_stack(state, stack_index, new_entry); | integrator_state_write_volume_stack(state, stack_index, new_entry); | ||||
| } | |||||
| ccl_device void integrator_intersect_volume_stack(KernelGlobals kg, IntegratorState state) | |||||
| { | |||||
| integrator_volume_stack_init(kg, state); | |||||
| if (INTEGRATOR_STATE(state, path, flag) & PATH_RAY_SHADOW_CATCHER_HIT) { | |||||
| /* Volume stack re-init for shadow catcher, continue with shading of hit. */ | |||||
| integrator_intersect_next_kernel_after_shadow_catcher_volume< | |||||
| DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK>(kg, state); | |||||
| } | |||||
| else { | |||||
| /* Volume stack init for camera rays, continue with intersection of camera ray. */ | |||||
| INTEGRATOR_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK, | INTEGRATOR_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK, | ||||
| DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST); | DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST); | ||||
| } | } | ||||
| } | |||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||