Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_light.h
| Show First 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | |||||
| #else | #else | ||||
| ccl_device | ccl_device | ||||
| #endif | #endif | ||||
| float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float *pdf) | float3 background_map_sample(KernelGlobals *kg, float randu, float randv, 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 = kernel_data.integrator.pdf_background_res; | int res_x = kernel_data.integrator.pdf_background_res_x; | ||||
| int cdf_count = res + 1; | int res_y = kernel_data.integrator.pdf_background_res_y; | ||||
| int cdf_width = res_x + 1; | |||||
| /* this is basically std::lower_bound as used by pbrt */ | /* this is basically std::lower_bound as used by pbrt */ | ||||
| int first = 0; | int first = 0; | ||||
| int count = res; | int count = res_y; | ||||
| while(count > 0) { | while(count > 0) { | ||||
| int step = count >> 1; | int step = count >> 1; | ||||
| int middle = first + step; | int middle = first + step; | ||||
| if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) { | if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) { | ||||
| first = middle + 1; | first = middle + 1; | ||||
| count -= step + 1; | count -= step + 1; | ||||
| } | } | ||||
| else | else | ||||
| count = step; | count = step; | ||||
| } | } | ||||
| int index_v = max(0, first - 1); | int index_v = max(0, first - 1); | ||||
| kernel_assert(index_v >= 0 && index_v < res); | kernel_assert(index_v >= 0 && index_v < res_y); | ||||
| float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); | float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); | ||||
| float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1); | float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1); | ||||
| float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res); | float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y); | ||||
| /* importance-sampled V direction */ | /* importance-sampled V direction */ | ||||
| float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv); | float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv); | ||||
| float v = (index_v + dv) / res; | float v = (index_v + dv) / res_y; | ||||
| /* this is basically std::lower_bound as used by pbrt */ | /* this is basically std::lower_bound as used by pbrt */ | ||||
| first = 0; | first = 0; | ||||
| count = res; | count = res_x; | ||||
| while(count > 0) { | while(count > 0) { | ||||
| int step = count >> 1; | int step = count >> 1; | ||||
| int middle = first + step; | int middle = first + step; | ||||
| if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) { | if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y < randu) { | ||||
| first = middle + 1; | first = middle + 1; | ||||
| count -= step + 1; | count -= step + 1; | ||||
| } | } | ||||
| else | else | ||||
| count = step; | count = step; | ||||
| } | } | ||||
| int index_u = max(0, first - 1); | int index_u = max(0, first - 1); | ||||
| kernel_assert(index_u >= 0 && index_u < res); | kernel_assert(index_u >= 0 && index_u < res_x); | ||||
| float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u); | float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u); | ||||
| float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1); | float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u + 1); | ||||
| float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res); | float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x); | ||||
| /* importance-sampled U direction */ | /* importance-sampled U direction */ | ||||
| float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu); | float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu); | ||||
| float u = (index_u + du) / res; | float u = (index_u + du) / res_x; | ||||
| /* compute pdf */ | /* compute pdf */ | ||||
| float denom = cdf_last_u.x * cdf_last_v.x; | float denom = cdf_last_u.x * cdf_last_v.x; | ||||
| float sin_theta = sinf(M_PI_F * v); | float sin_theta = sinf(M_PI_F * v); | ||||
| if(sin_theta == 0.0f || denom == 0.0f) | if(sin_theta == 0.0f || denom == 0.0f) | ||||
| *pdf = 0.0f; | *pdf = 0.0f; | ||||
| else | else | ||||
| Show All 9 Lines | |||||
| #ifdef __KERNEL_GPU__ | #ifdef __KERNEL_GPU__ | ||||
| ccl_device_noinline | ccl_device_noinline | ||||
| #else | #else | ||||
| ccl_device | ccl_device | ||||
| #endif | #endif | ||||
| float background_map_pdf(KernelGlobals *kg, float3 direction) | float background_map_pdf(KernelGlobals *kg, float3 direction) | ||||
| { | { | ||||
| float2 uv = direction_to_equirectangular(direction); | float2 uv = direction_to_equirectangular(direction); | ||||
| int res = kernel_data.integrator.pdf_background_res; | int res_x = kernel_data.integrator.pdf_background_res_x; | ||||
| int res_y = kernel_data.integrator.pdf_background_res_y; | |||||
| int cdf_width = res_x + 1; | |||||
| float sin_theta = sinf(uv.y * M_PI_F); | float sin_theta = sinf(uv.y * M_PI_F); | ||||
| if(sin_theta == 0.0f) | if(sin_theta == 0.0f) | ||||
| return 0.0f; | return 0.0f; | ||||
| int index_u = clamp(float_to_int(uv.x * res), 0, res - 1); | int index_u = clamp(float_to_int(uv.x * res_x), 0, res_x - 1); | ||||
| int index_v = clamp(float_to_int(uv.y * res), 0, res - 1); | int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1); | ||||
| /* pdfs in V direction */ | /* pdfs in V direction */ | ||||
| float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res); | float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x); | ||||
| float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res); | float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y); | ||||
| float denom = cdf_last_u.x * cdf_last_v.x; | float denom = cdf_last_u.x * cdf_last_v.x; | ||||
| if(denom == 0.0f) | if(denom == 0.0f) | ||||
| return 0.0f; | return 0.0f; | ||||
| /* pdfs in U direction */ | /* pdfs in U direction */ | ||||
| float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u); | float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, 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)/(M_2PI_F * M_PI_F * sin_theta * denom); | return (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom); | ||||
| } | } | ||||
| ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals *kg, | ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals *kg, | ||||
| float3 P, | float3 P, | ||||
| int index, | int index, | ||||
| ▲ Show 20 Lines • Show All 866 Lines • Show Last 20 Lines | |||||