Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_light_background.h
| Show All 18 Lines | |||||
| #include "kernel_light_common.h" | #include "kernel_light_common.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| /* Background Light */ | /* Background Light */ | ||||
| #ifdef __BACKGROUND_MIS__ | #ifdef __BACKGROUND_MIS__ | ||||
| ccl_device float3 background_map_sample(ccl_global const KernelGlobals *kg, | ccl_device float3 background_map_sample(KernelGlobals kg, | ||||
| float randu, | float randu, | ||||
| float randv, | float randv, | ||||
| ccl_private float *pdf) | ccl_private float *pdf) | ||||
| { | { | ||||
| /* for the following, the CDF values are actually a pair of floats, with the | /* for the following, the CDF values are actually a pair of floats, with the | ||||
| * function value as X and the actual CDF as Y. The last entry's function | * function value as X and the actual CDF as Y. The last entry's function | ||||
| * value is the CDF total. */ | * value is the CDF total. */ | ||||
| int res_x = kernel_data.background.map_res_x; | int res_x = kernel_data.background.map_res_x; | ||||
| ▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | ccl_device float3 background_map_sample(KernelGlobals kg, | ||||
| /* compute direction */ | /* compute direction */ | ||||
| return equirectangular_to_direction(u, v); | return equirectangular_to_direction(u, v); | ||||
| } | } | ||||
| /* TODO(sergey): Same as above, after the release we should consider using | /* TODO(sergey): Same as above, after the release we should consider using | ||||
| * 'noinline' for all devices. | * 'noinline' for all devices. | ||||
| */ | */ | ||||
| ccl_device float background_map_pdf(ccl_global const KernelGlobals *kg, float3 direction) | ccl_device float background_map_pdf(KernelGlobals kg, float3 direction) | ||||
| { | { | ||||
| float2 uv = direction_to_equirectangular(direction); | float2 uv = direction_to_equirectangular(direction); | ||||
| int res_x = kernel_data.background.map_res_x; | int res_x = kernel_data.background.map_res_x; | ||||
| int res_y = kernel_data.background.map_res_y; | int res_y = kernel_data.background.map_res_y; | ||||
| int cdf_width = res_x + 1; | int cdf_width = res_x + 1; | ||||
| float sin_theta = sinf(uv.y * M_PI_F); | float sin_theta = sinf(uv.y * M_PI_F); | ||||
| Show All 17 Lines | ccl_device float background_map_pdf(KernelGlobals kg, float3 direction) | ||||
| float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, | float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, | ||||
| index_v * cdf_width + index_u); | index_v * cdf_width + index_u); | ||||
| float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); | float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); | ||||
| return (cdf_u.x * cdf_v.x) / denom; | return (cdf_u.x * cdf_v.x) / denom; | ||||
| } | } | ||||
| ccl_device_inline bool background_portal_data_fetch_and_check_side( | ccl_device_inline bool background_portal_data_fetch_and_check_side( | ||||
| ccl_global const KernelGlobals *kg, | KernelGlobals kg, float3 P, int index, ccl_private float3 *lightpos, ccl_private float3 *dir) | ||||
| float3 P, | |||||
| int index, | |||||
| ccl_private float3 *lightpos, | |||||
| ccl_private float3 *dir) | |||||
| { | { | ||||
| int portal = kernel_data.background.portal_offset + index; | int portal = kernel_data.background.portal_offset + index; | ||||
| const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal); | const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal); | ||||
| *lightpos = make_float3(klight->co[0], klight->co[1], klight->co[2]); | *lightpos = make_float3(klight->co[0], klight->co[1], klight->co[2]); | ||||
| *dir = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); | *dir = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); | ||||
| /* Check whether portal is on the right side. */ | /* Check whether portal is on the right side. */ | ||||
| if (dot(*dir, P - *lightpos) > 1e-4f) | if (dot(*dir, P - *lightpos) > 1e-4f) | ||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| ccl_device_inline float background_portal_pdf(ccl_global const KernelGlobals *kg, | ccl_device_inline float background_portal_pdf( | ||||
| float3 P, | KernelGlobals kg, float3 P, float3 direction, int ignore_portal, ccl_private bool *is_possible) | ||||
| float3 direction, | |||||
| int ignore_portal, | |||||
| ccl_private bool *is_possible) | |||||
| { | { | ||||
| float portal_pdf = 0.0f; | float portal_pdf = 0.0f; | ||||
| int num_possible = 0; | int num_possible = 0; | ||||
| for (int p = 0; p < kernel_data.background.num_portals; p++) { | for (int p = 0; p < kernel_data.background.num_portals; p++) { | ||||
| if (p == ignore_portal) | if (p == ignore_portal) | ||||
| continue; | continue; | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | ccl_device_inline float background_portal_pdf( | ||||
| if (ignore_portal >= 0) { | if (ignore_portal >= 0) { | ||||
| /* We have skipped a portal that could be sampled as well. */ | /* We have skipped a portal that could be sampled as well. */ | ||||
| num_possible++; | num_possible++; | ||||
| } | } | ||||
| return (num_possible > 0) ? portal_pdf / num_possible : 0.0f; | return (num_possible > 0) ? portal_pdf / num_possible : 0.0f; | ||||
| } | } | ||||
| ccl_device int background_num_possible_portals(ccl_global const KernelGlobals *kg, float3 P) | ccl_device int background_num_possible_portals(KernelGlobals kg, float3 P) | ||||
| { | { | ||||
| int num_possible_portals = 0; | int num_possible_portals = 0; | ||||
| for (int p = 0; p < kernel_data.background.num_portals; p++) { | for (int p = 0; p < kernel_data.background.num_portals; p++) { | ||||
| float3 lightpos, dir; | float3 lightpos, dir; | ||||
| if (background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir)) | if (background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir)) | ||||
| num_possible_portals++; | num_possible_portals++; | ||||
| } | } | ||||
| return num_possible_portals; | return num_possible_portals; | ||||
| } | } | ||||
| ccl_device float3 background_portal_sample(ccl_global const KernelGlobals *kg, | ccl_device float3 background_portal_sample(KernelGlobals kg, | ||||
| float3 P, | float3 P, | ||||
| float randu, | float randu, | ||||
| float randv, | float randv, | ||||
| int num_possible, | int num_possible, | ||||
| ccl_private int *sampled_portal, | ccl_private int *sampled_portal, | ||||
| ccl_private float *pdf) | ccl_private float *pdf) | ||||
| { | { | ||||
| /* Pick a portal, then re-normalize randv. */ | /* Pick a portal, then re-normalize randv. */ | ||||
| Show All 38 Lines | for (int p = 0; p < kernel_data.background.num_portals; p++) { | ||||
| } | } | ||||
| portal--; | portal--; | ||||
| } | } | ||||
| return zero_float3(); | return zero_float3(); | ||||
| } | } | ||||
| ccl_device_inline float3 background_sun_sample(ccl_global const KernelGlobals *kg, | ccl_device_inline float3 background_sun_sample(KernelGlobals kg, | ||||
| float randu, | float randu, | ||||
| float randv, | float randv, | ||||
| ccl_private float *pdf) | ccl_private float *pdf) | ||||
| { | { | ||||
| float3 D; | float3 D; | ||||
| const float3 N = float4_to_float3(kernel_data.background.sun); | const float3 N = float4_to_float3(kernel_data.background.sun); | ||||
| const float angle = kernel_data.background.sun.w; | const float angle = kernel_data.background.sun.w; | ||||
| sample_uniform_cone(N, angle, randu, randv, &D, pdf); | sample_uniform_cone(N, angle, randu, randv, &D, pdf); | ||||
| return D; | return D; | ||||
| } | } | ||||
| ccl_device_inline float background_sun_pdf(ccl_global const KernelGlobals *kg, float3 D) | ccl_device_inline float background_sun_pdf(KernelGlobals kg, float3 D) | ||||
| { | { | ||||
| const float3 N = float4_to_float3(kernel_data.background.sun); | const float3 N = float4_to_float3(kernel_data.background.sun); | ||||
| const float angle = kernel_data.background.sun.w; | const float angle = kernel_data.background.sun.w; | ||||
| return pdf_uniform_cone(N, D, angle); | return pdf_uniform_cone(N, D, angle); | ||||
| } | } | ||||
| ccl_device_inline float3 background_light_sample( | ccl_device_inline float3 background_light_sample( | ||||
| ccl_global const KernelGlobals *kg, float3 P, float randu, float randv, ccl_private float *pdf) | KernelGlobals kg, float3 P, float randu, float randv, ccl_private float *pdf) | ||||
| { | { | ||||
| float portal_method_pdf = kernel_data.background.portal_weight; | float portal_method_pdf = kernel_data.background.portal_weight; | ||||
| float sun_method_pdf = kernel_data.background.sun_weight; | float sun_method_pdf = kernel_data.background.sun_weight; | ||||
| float map_method_pdf = kernel_data.background.map_weight; | float map_method_pdf = kernel_data.background.map_weight; | ||||
| int num_portals = 0; | int num_portals = 0; | ||||
| if (portal_method_pdf > 0.0f) { | if (portal_method_pdf > 0.0f) { | ||||
| /* Check if there are portals in the scene which we can sample. */ | /* Check if there are portals in the scene which we can sample. */ | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | if (method != 1 && sun_method_pdf != 0.0f) { | ||||
| *pdf += sun_method_pdf * background_sun_pdf(kg, D); | *pdf += sun_method_pdf * background_sun_pdf(kg, D); | ||||
| } | } | ||||
| if (method != 2 && map_method_pdf != 0.0f) { | if (method != 2 && map_method_pdf != 0.0f) { | ||||
| *pdf += map_method_pdf * background_map_pdf(kg, D); | *pdf += map_method_pdf * background_map_pdf(kg, D); | ||||
| } | } | ||||
| return D; | return D; | ||||
| } | } | ||||
| ccl_device float background_light_pdf(ccl_global const KernelGlobals *kg, | ccl_device float background_light_pdf(KernelGlobals kg, float3 P, float3 direction) | ||||
| float3 P, | |||||
| float3 direction) | |||||
| { | { | ||||
| float portal_method_pdf = kernel_data.background.portal_weight; | float portal_method_pdf = kernel_data.background.portal_weight; | ||||
| float sun_method_pdf = kernel_data.background.sun_weight; | float sun_method_pdf = kernel_data.background.sun_weight; | ||||
| float map_method_pdf = kernel_data.background.map_weight; | float map_method_pdf = kernel_data.background.map_weight; | ||||
| float portal_pdf = 0.0f; | float portal_pdf = 0.0f; | ||||
| /* Portals are a special case here since we need to compute their pdf in order | /* Portals are a special case here since we need to compute their pdf in order | ||||
| * to find out if we can sample them. */ | * to find out if we can sample them. */ | ||||
| Show All 37 Lines | |||||