Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/light/tree.h
| Show First 20 Lines • Show All 545 Lines • ▼ Show 20 Lines | ccl_device bool light_tree_sample(KernelGlobals kg, | ||||
| float randv, | float randv, | ||||
| const float time, | const float time, | ||||
| const float3 P, | const float3 P, | ||||
| const float3 N_or_D, | const float3 N_or_D, | ||||
| const float t, | const float t, | ||||
| const int shader_flags, | const int shader_flags, | ||||
| const int bounce, | const int bounce, | ||||
| const uint32_t path_flag, | const uint32_t path_flag, | ||||
| ccl_private LightSample *ls) | ccl_private int *emitter_object, | ||||
| ccl_private int *emitter_prim, | |||||
| ccl_private int *emitter_shader_flag, | |||||
| ccl_private float *emitter_pdf_selection) | |||||
| { | { | ||||
| if (!kernel_data.integrator.use_direct_light) { | if (!kernel_data.integrator.use_direct_light) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION); | const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION); | ||||
| float pdf_leaf = 1.0f; | float pdf_leaf = 1.0f; | ||||
| float pdf_emitter_from_leaf = 1.0f; | float pdf_emitter_from_leaf = 1.0f; | ||||
| Show All 29 Lines | while (true) { | ||||
| sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randu); | sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randu); | ||||
| pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); | pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); | ||||
| } | } | ||||
| if (selected_light < 0) { | if (selected_light < 0) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Sample a point on the chosen emitter */ | /* Return info about chosen emitter. */ | ||||
| ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, | ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, | ||||
| selected_light); | selected_light); | ||||
| /* TODO: this is the same code as light_distribution_sample, except the index is determined | *emitter_object = kemitter->mesh_light.object_id; | ||||
| * differently. Would it be better to refactor this into a separate function? */ | *emitter_prim = kemitter->prim_id; | ||||
| const int prim = kemitter->prim_id; | *emitter_shader_flag = kemitter->mesh_light.shader_flag; | ||||
| if (prim >= 0) { | *emitter_pdf_selection = pdf_leaf * pdf_emitter_from_leaf; | ||||
| /* Mesh light. */ | |||||
| const int object = kemitter->mesh_light.object_id; | |||||
| /* Exclude synthetic meshes from shadow catcher pass. */ | |||||
| if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && | |||||
| !(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { | |||||
| return false; | |||||
| } | |||||
| const int mesh_shader_flag = kemitter->mesh_light.shader_flag; | |||||
| if (!triangle_light_sample<in_volume_segment>(kg, prim, object, randu, randv, time, ls, P)) { | |||||
| return false; | |||||
| } | |||||
| ls->shader |= mesh_shader_flag; | |||||
| } | |||||
| else { | |||||
| if (UNLIKELY(light_select_reached_max_bounces(kg, ~prim, bounce))) { | |||||
| return false; | |||||
| } | |||||
| if (!light_sample<in_volume_segment>(kg, ~prim, randu, randv, P, path_flag, ls)) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| ls->pdf_selection = pdf_leaf * pdf_emitter_from_leaf; | return true; | ||||
| ls->pdf *= ls->pdf_selection; | |||||
| return (ls->pdf > 0); | |||||
| } | } | ||||
| /* We need to be able to find the probability of selecting a given light for MIS. */ | /* We need to be able to find the probability of selecting a given light for MIS. */ | ||||
| ccl_device float light_tree_pdf( | ccl_device float light_tree_pdf( | ||||
| KernelGlobals kg, const float3 P, const float3 N, const int path_flag, const int prim) | KernelGlobals kg, const float3 P, const float3 N, const int path_flag, const int prim) | ||||
| { | { | ||||
| const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION); | const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION); | ||||
| /* Target emitter info */ | /* Target emitter info */ | ||||
| ▲ Show 20 Lines • Show All 72 Lines • Show Last 20 Lines | |||||