Commit: 36cfc9e9fdc12beeec3545854bb2ccbb23ef17c6 Author: Erik Englesson Date: Tue Jul 3 10:36:58 2018 +0200 Branches: gsoc-2018-many-light-sampling https://developer.blender.org/rB36cfc9e9fdc12beeec3545854bb2ccbb23ef17c6
Cycles: First iteration on split traversal This makes it possible to sample and evaluate several lights in a single tree traversal. Should sample highly specular lights better too. Can only be used in branched path tracing. This commit contains the following: * GUI for setting the splitting threshold * Recursive split traversal - Split method based on solid angle and BSDF peak - At leafs the path radiance is accumulated to L - Have created a simplified GGX eval that is not currently being used. * Refactor of common code This is in development. =================================================================== M intern/cycles/blender/addon/presets.py M intern/cycles/blender/addon/properties.py M intern/cycles/blender/addon/ui.py M intern/cycles/blender/blender_sync.cpp M intern/cycles/kernel/closure/bsdf_microfacet.h M intern/cycles/kernel/kernel_light.h M intern/cycles/kernel/kernel_path_surface.h M intern/cycles/kernel/kernel_types.h M intern/cycles/render/integrator.h M intern/cycles/render/light.cpp =================================================================== diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py index ca9edd0c600..85e075a5167 100644 --- a/intern/cycles/blender/addon/presets.py +++ b/intern/cycles/blender/addon/presets.py @@ -69,6 +69,7 @@ class AddPresetSampling(AddPresetBase, Operator): "cycles.volume_samples", "cycles.use_square_samples", "cycles.use_light_bvh", + "cycles.splitting_threshold", "cycles.progressive", "cycles.seed", "cycles.sample_clamp_direct", diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index dac9844a11c..b2df2c927e9 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -195,6 +195,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=False, ) + cls.splitting_threshold = FloatProperty( + name="Splitting", + description="Threshold for splitting. 0.0=one light, 1.0=all lights", + min=0.0, max=1.0, + default=0.0, + ) + cls.samples = IntProperty( name="Samples", description="Number of samples to render for each pixel", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index bb1b7bee1f4..f7ceddba4a5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -214,6 +214,10 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): row = layout.row(align=True) row.label(text="Experimental:") row.prop(cscene, "use_light_bvh", text="Light BVH") + if cscene.use_light_bvh and use_branched_path(context): + row = layout.row(align=True) + row.label(text="") # create empty column + row.prop(cscene, "splitting_threshold", text="Splitting") draw_samples_info(layout, context) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 49acba9304d..74169a30f53 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -282,6 +282,7 @@ void BlenderSync::sync_integrator() Integrator::PATH); integrator->use_light_bvh = get_boolean(cscene, "use_light_bvh"); + integrator->splitting_threshold = get_float(cscene, "splitting_threshold"); integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct"); integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect"); integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold"); diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 2dd59354058..369beee1d2c 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -391,6 +391,81 @@ ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y); } +/* TODO: Use this in the tree traversal splitting */ +ccl_device float3 bsdf_microfacet_ggx_eval_reflect_simple(const ShaderClosure *sc, const float3 I, const float3 omega_in) +{ + const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; + float alpha_x = bsdf->alpha_x; + float alpha_y = bsdf->alpha_y; + bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + float3 N = bsdf->N; + + if(m_refractive || alpha_x*alpha_y <= 1e-7f) + return make_float3(0.0f, 0.0f, 0.0f); + + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); // pass in our conservative cosine instead of this one? + // fresnel calcs some kind of cosine with I too. + + if(cosNI > 0 && cosNO > 0) { + /* get half vector */ + float3 m = normalize(omega_in + I); + float alpha2 = alpha_x * alpha_y; + float D, G1o, G1i; + + /* assume isotropic */ + + /* isotropic + * eq. 20: (F*G*D)/(4*in*on) + * eq. 33: first we calculate D(m) */ + float cosThetaM = dot(N, m); + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; + + /* use GTR2 */ + D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + + /* eq. 34: now calculate G1(i,m) and G1(o,m) */ + //G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + //G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + + /* Let a2=alpha2 and cos=cosNO/cosNI then the above is equivalent to: + * 2 / ( 1 + sqrt( 1 + a2 * (1 - cos^2) / cos^2 ) ) = /common denom/ = + * 2 / ( 1 + sqrt( (cos^2 + a2 * (1 - cos^2)) / cos^2 ) ) = /factor out 1/cos^2/ = + * 2 / ( 1 + sqrt( cos^2 + a2 * (1 - cos^2) ) / cos ) = /common denom/ = + * 2 / ( (cos + sqrt( cos^2 + a2 * (1 - cos^2) ) ) / cos = /move cos to num/ = + * 2cos / ( cos + sqrt( cos^2 + a2 * (1 - cos^2) ) ) = /rewrite sqrt/ = + * 2cos / ( cos + sqrt( cos^2 * (1 - a2) + a2 ) ) + * => removes one of the divisions + * + * - Glo should contain a cosNO in its numerator but this cancels with + * cosNO in the denomenator in eq. 20.(removes another division) + * - There should be a cosNI in the denomenator of eq. 20 but I think + * this has been canceled out already since there is no cosNI in + * path_radiance_bsdf_bounce() ? + * - Both Glo and Gli should contain a 2.0 in their numerators but they + * cancel with 1/4 in eq. 20. + * + * => This code does three less divisions in total + * This could potentially be used in the real GGX evaluation too. + */ + G1o = 1.0f / (cosNO + safe_sqrtf(cosNO * cosNO * (1.0f - alpha2) + alpha2)); + G1i = cosNI / (cosNI + safe_sqrtf(cosNI * cosNI * (1.0f - alpha2) + alpha2)); + + float G = G1o * G1i; + + /* eq. 20 */ + float3 F = reflection_color(bsdf, omega_in, m); + + float3 out = F * G * D; + + return out; + } + + return make_float3(0.0f, 0.0f, 0.0f); +} + ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 22804c58aa8..39d575adefa 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -1122,6 +1122,7 @@ ccl_device float calc_node_importance(KernelGlobals *kg, float3 P, int node_offs float theta_u = 0; // TODO: Figure out how to calculate this one float d2 = len_squared(centroidToP); + // todo: fix clamp here so it is 0 outside theta_e + theta_o ? return energy * cosf(clamp(theta - theta_o - theta_u, 0.0, theta_e))/d2; } @@ -1378,22 +1379,18 @@ ccl_device void light_distribution_sample(KernelGlobals *kg, float3 P, } } -/* picks a point on a light and computes the probability of picking this point*/ -ccl_device_noinline bool light_sample(KernelGlobals *kg, - float randu, - float randv, - float time, - float3 P, - int bounce, - LightSample *ls) +/* picks a point on a given light and computes the probability of picking this point*/ +ccl_device void light_point_sample(KernelGlobals *kg, + float randu, + float randv, + float time, + float3 P, + int bounce, + int distribution_id, + LightSample *ls) { - /* sample index and compute light picking pdf */ - float pdf_factor = 0.0f; - int index = -1; - light_distribution_sample(kg, P, &randu, &index, &pdf_factor); - /* fetch light data and compute rest of light pdf */ - const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution, index); + const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution, distribution_id); int prim = kdistribution->prim; if(prim >= 0) { @@ -1407,13 +1404,31 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg, int lamp = -prim-1; if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - return false; + ls->pdf = 0.0f; + return; } if (!lamp_light_sample(kg, lamp, randu, randv, P, ls)){ - return false; + ls->pdf = 0.0f; + return; } } +} + +/* picks a point on a light and computes the probability of picking this point*/ +ccl_device_noinline bool light_sample(KernelGlobals *kg, + float randu, + float randv, + float time, + float3 P, + int bounce, + LightSample *ls) +{ + /* sample index and compute light picking pdf */ + float pdf_factor = 0.0f; + int index = -1; + light_distribution_sample(kg, P, &randu, &index, &pdf_factor); + light_point_sample(kg, randu, randv, time, P, bounce, index, ls); /* combine pdfs */ ls->pdf *= pdf_factor; diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index f69fadb6669..54062a1c2b7 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -14,8 +14,238 @@ * limitations under the License. */ +#include "util/util_logging.h" + CCL_NAMESPACE_BEGIN +ccl_device void accum_light_contribution(KernelGlobals *kg, + ShaderData *sd, + ShaderData* emission_sd, + LightSamp @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs