Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/light/tree.h
| Show First 20 Lines • Show All 535 Lines • ▼ Show 20 Lines | const float probability_min = total_min_importance > 0 ? | ||||
| 0.5f * (float(max_left_importance > 0) + | 0.5f * (float(max_left_importance > 0) + | ||||
| float(max_right_importance == 0.0f)); | float(max_right_importance == 0.0f)); | ||||
| left_probability = 0.5f * (probability_max + probability_min); | left_probability = 0.5f * (probability_max + probability_min); | ||||
| return true; | return true; | ||||
| } | } | ||||
| template<bool in_volume_segment> | template<bool in_volume_segment> | ||||
| ccl_device_noinline bool light_tree_sample(KernelGlobals kg, | ccl_device_noinline bool light_tree_sample(KernelGlobals kg, | ||||
| ccl_private float &randu, | float randu, | ||||
| ccl_private 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 int &emitter_object, | ccl_private LightSample *ls) | ||||
| 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; | ||||
| } | } | ||||
| /* Return info about chosen emitter. */ | /* Sample a point on the 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); | ||||
| emitter_object = kemitter->mesh_light.object_id; | /* TODO: this is the same code as light_distribution_sample, except the index is determined | ||||
| emitter_prim = kemitter->prim_id; | * differently. Would it be better to refactor this into a separate function? */ | ||||
| emitter_shader_flag = kemitter->mesh_light.shader_flag; | const int prim = kemitter->prim_id; | ||||
| emitter_pdf_selection = pdf_leaf * pdf_emitter_from_leaf; | if (prim >= 0) { | ||||
| /* Mesh light. */ | |||||
| const int object = kemitter->mesh_light.object_id; | |||||
| return true; | /* 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; | |||||
| 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 | |||||