From 716e138a1b8cb81e13f7da2da5d16763d868743a Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Thu, 14 Jun 2018 16:18:34 +0200 Subject: Cycles: Automatically detect HDRI resolution by default and use non-square sampling map The automatic mode checks all Enviroment Texture nodes and picks the largest image's resolution. If there are no Enviroment Textures, it just uses the old default. Also, the sampling map now isn't limited to square shapes. The automatic detection uses the exact image size, the manual UI option now halves the value to get the height. A default aspect ratio of 2:1 makes sense since this is what most HDRIs use. Reviewers: brecht, sergey Differential Revision: https://developer.blender.org/D3477 --- intern/cycles/kernel/kernel_light.h | 41 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'intern/cycles/kernel/kernel_light.h') diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index ec7203d36eb..bb182ef1f25 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -143,12 +143,13 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float /* 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 * value is the CDF total. */ - int res = kernel_data.integrator.pdf_background_res; - int cdf_count = res + 1; + 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; /* this is basically std::lower_bound as used by pbrt */ int first = 0; - int count = res; + int count = res_y; while(count > 0) { int step = count >> 1; @@ -163,24 +164,24 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float } 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_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 */ 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 */ first = 0; - count = res; + count = res_x; while(count > 0) { int step = count >> 1; 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; count -= step + 1; } @@ -189,15 +190,15 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float } 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_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1); - float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res); + 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_width + index_u + 1); + float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x); /* importance-sampled U direction */ 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 */ float denom = cdf_last_u.x * cdf_last_v.x; @@ -223,19 +224,21 @@ ccl_device float background_map_pdf(KernelGlobals *kg, float3 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); if(sin_theta == 0.0f) return 0.0f; - int index_u = clamp(float_to_int(uv.x * res), 0, res - 1); - int index_v = clamp(float_to_int(uv.y * 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_y), 0, res_y - 1); /* pdfs in V direction */ - float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res); - float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, 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_y); float denom = cdf_last_u.x * cdf_last_v.x; @@ -243,7 +246,7 @@ float background_map_pdf(KernelGlobals *kg, float3 direction) return 0.0f; /* 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); return (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom); -- cgit v1.2.3