Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
| Show All 17 Lines | |||||
| #include "kernel/bvh/bvh.h" | #include "kernel/bvh/bvh.h" | ||||
| #include "kernel/geom/geom.h" | #include "kernel/geom/geom.h" | ||||
| #include "kernel/integrator/integrator_volume_stack.h" | #include "kernel/integrator/integrator_volume_stack.h" | ||||
| #include "kernel/kernel_shader.h" | #include "kernel/kernel_shader.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| ccl_device void integrator_volume_stack_update_for_subsurface(INTEGRATOR_STATE_ARGS, | ccl_device void integrator_volume_stack_update_for_subsurface(KernelGlobals kg, | ||||
| IntegratorState state, | |||||
| const float3 from_P, | const float3 from_P, | ||||
| const float3 to_P) | const float3 to_P) | ||||
| { | { | ||||
| 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); | ||||
| Show All 12 Lines | 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, PATH_RAY_ALL_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(INTEGRATOR_STATE_PASS, 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, PATH_RAY_ALL_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(INTEGRATOR_STATE_PASS, 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(INTEGRATOR_STATE_ARGS) | ccl_device void integrator_intersect_volume_stack(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(INTEGRATOR_STATE_PASS, &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(path, flag) & PATH_RAY_ALL_VISIBILITY); | 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. */ | /* Write 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}; | const VolumeStack new_entry = {OBJECT_NONE, kernel_data.background.volume_shader}; | ||||
| integrator_state_write_volume_stack(INTEGRATOR_STATE_PASS, stack_index, new_entry); | 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; | ||||
| #ifdef __VOLUME_RECORD_ALL__ | #ifdef __VOLUME_RECORD_ALL__ | ||||
| Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | Intersection hits[2 * MAX_VOLUME_STACK_SIZE + 1]; | ||||
| Show All 14 Lines | for (uint hit = 0; hit < num_hits; ++hit, ++isect) { | ||||
| * it means that camera is inside such a volume. | * it means that camera is inside such a volume. | ||||
| */ | */ | ||||
| if (enclosed_volumes[i] == stack_sd->object) { | if (enclosed_volumes[i] == stack_sd->object) { | ||||
| need_add = false; | need_add = false; | ||||
| } | } | ||||
| } | } | ||||
| for (int i = 0; i < stack_index && need_add; ++i) { | for (int i = 0; i < stack_index && need_add; ++i) { | ||||
| /* Don't add intersections twice. */ | /* Don't add intersections twice. */ | ||||
| VolumeStack entry = integrator_state_read_volume_stack(INTEGRATOR_STATE_PASS, i); | VolumeStack entry = integrator_state_read_volume_stack(state, i); | ||||
| if (entry.object == stack_sd->object) { | if (entry.object == stack_sd->object) { | ||||
| need_add = false; | need_add = false; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (need_add && stack_index < volume_stack_size - 1) { | if (need_add && stack_index < volume_stack_size - 1) { | ||||
| const VolumeStack new_entry = {stack_sd->object, stack_sd->shader}; | const VolumeStack new_entry = {stack_sd->object, stack_sd->shader}; | ||||
| integrator_state_write_volume_stack(INTEGRATOR_STATE_PASS, stack_index, new_entry); | integrator_state_write_volume_stack(state, stack_index, new_entry); | ||||
| ++stack_index; | ++stack_index; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If ray from camera enters the volume, this volume shouldn't | /* If ray from camera enters the volume, this volume shouldn't | ||||
| * be added to the stack on exit. | * be added to the stack on exit. | ||||
| */ | */ | ||||
| enclosed_volumes[enclosed_index++] = stack_sd->object; | enclosed_volumes[enclosed_index++] = stack_sd->object; | ||||
| Show All 23 Lines | if (stack_sd->flag & SD_BACKFACING) { | ||||
| * it means that camera is inside such a volume. | * it means that camera is inside such a volume. | ||||
| */ | */ | ||||
| if (enclosed_volumes[i] == stack_sd->object) { | if (enclosed_volumes[i] == stack_sd->object) { | ||||
| need_add = false; | need_add = false; | ||||
| } | } | ||||
| } | } | ||||
| for (int i = 0; i < stack_index && need_add; ++i) { | for (int i = 0; i < stack_index && need_add; ++i) { | ||||
| /* Don't add intersections twice. */ | /* Don't add intersections twice. */ | ||||
| VolumeStack entry = integrator_state_read_volume_stack(INTEGRATOR_STATE_PASS, i); | VolumeStack entry = integrator_state_read_volume_stack(state, i); | ||||
| if (entry.object == stack_sd->object) { | if (entry.object == stack_sd->object) { | ||||
| need_add = false; | need_add = false; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (need_add) { | if (need_add) { | ||||
| const VolumeStack new_entry = {stack_sd->object, stack_sd->shader}; | const VolumeStack new_entry = {stack_sd->object, stack_sd->shader}; | ||||
| integrator_state_write_volume_stack(INTEGRATOR_STATE_PASS, stack_index, new_entry); | integrator_state_write_volume_stack(state, stack_index, new_entry); | ||||
| ++stack_index; | ++stack_index; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If ray from camera enters the volume, this volume shouldn't | /* If ray from camera enters the volume, this volume shouldn't | ||||
| * be added to the stack on exit. | * be added to the stack on exit. | ||||
| */ | */ | ||||
| enclosed_volumes[enclosed_index++] = stack_sd->object; | enclosed_volumes[enclosed_index++] = stack_sd->object; | ||||
| } | } | ||||
| /* 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); | ||||
| ++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(INTEGRATOR_STATE_PASS, stack_index, new_entry); | integrator_state_write_volume_stack(state, stack_index, new_entry); | ||||
| 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 | ||||