Commit: f55d6816ecd463b4d9ad5d3848a8ecc53723e083 Author: Sebastian Herholz Date: Thu Jan 26 19:50:20 2023 +0100 Branches: cycles_path_guiding https://developer.blender.org/rBf55d6816ecd463b4d9ad5d3848a8ecc53723e083
Guiding: Added roughness-based MIS guiding type and fixed sss bug with RIS =================================================================== M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/integrator/surface_shader.h M intern/cycles/kernel/light/visibility.h =================================================================== diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index cc81dae8af0..8a52ab74a2a 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -372,7 +372,9 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 if (kernel_data.integrator.use_surface_guiding) { if (kernel_data.integrator.guiding_directional_sampling_type == - GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT) { + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT || + kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS) { label = surface_shader_bsdf_guided_sample_closure_mis(kg, state, sd, diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index 56707523f33..60eaed2c4ee 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -26,6 +26,24 @@ CCL_NAMESPACE_BEGIN /* Guiding */ #ifdef __PATH_GUIDING__ + +ccl_device float surface_shader_average_sample_weight_squared_roughness(ccl_private const ShaderData *sd){ + float avg_roughness = 0.0f; + float sum_sample_weight = 0.0f; + for (int i = 0; i < sd->num_closure; i++) { + ccl_private const ShaderClosure *sc = &sd->closure[i]; + + if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { + continue; + } + avg_roughness += sc->sample_weight * bsdf_get_specular_roughness_squared(sc); + sum_sample_weight += sc->sample_weight; + } + + avg_roughness = avg_roughness > 0.f ? avg_roughness / sum_sample_weight : 0.f; + return avg_roughness; +} + ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, @@ -38,6 +56,8 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, } const float surface_guiding_probability = kernel_data.integrator.surface_guiding_probability; + const int guiding_directional_sampling_type = + kernel_data.integrator.guiding_directional_sampling_type; float rand_bsdf_guiding = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_BSDF_GUIDING); /* Compute proportion of diffuse BSDF and BSSRDFs .*/ @@ -45,6 +65,8 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, float bssrdf_sampling_fraction = 0.0f; float bsdf_bssrdf_sampling_sum = 0.0f; + bool fully_opaque = true; + for (int i = 0; i < sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { @@ -58,6 +80,10 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, if (CLOSURE_IS_BSSRDF(sc->type)) { bssrdf_sampling_fraction += sweight; } + + if (CLOSURE_IS_BSDF_TRANSPARENT(sc->type) || CLOSURE_IS_BSDF_TRANSMISSION(sc->type)) { + fully_opaque = false; + } } } @@ -66,16 +92,31 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, bssrdf_sampling_fraction /= bsdf_bssrdf_sampling_sum; } + float avg_roughness = surface_shader_average_sample_weight_squared_roughness(sd); + /* Init guiding (diffuse BSDFs only for now). */ - if (!(diffuse_sampling_fraction > 0.0f && - guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding))) { + if (!fully_opaque || avg_roughness <= 0.05f || + ((guiding_directional_sampling_type == GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT) && + (diffuse_sampling_fraction <= 0.f)) || + !guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding)) { state->guiding.use_surface_guiding = false; + state->guiding.surface_guiding_sampling_prob = 0.0f; return; } state->guiding.use_surface_guiding = true; - state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * - diffuse_sampling_fraction; + if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT) { + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * + diffuse_sampling_fraction; + } + else if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS) { + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability; + } + else { // GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * avg_roughness; + } state->guiding.bssrdf_sampling_prob = bssrdf_sampling_fraction; state->guiding.sample_surface_guiding_rand = rand_bsdf_guiding; @@ -550,7 +591,6 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, kernel_assert(CLOSURE_IS_BSDF(sc->type)); const bool use_surface_guiding = state->guiding.use_surface_guiding; - // const bool use_surface_guiding = true; const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob; const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob; @@ -601,8 +641,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, &eta_ris[0]); bsdf_eval_init(&bsdf_evals[0], sc->type, evals[0] * sc->weight); - if(bsdf_pdfs[0] > 0.f) - { + if (bsdf_pdfs[0] > 0.f) { cosines[0] = max(0.01f, fabsf(dot(sd->N, omega_in_ris[0]))); if (sd->num_closure > 1) { float sweight = sc->sample_weight; @@ -613,19 +652,16 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, avg_bsdf_evals[0] = (bsdf_evals[0].sum[0] + bsdf_evals[0].sum[1] + bsdf_evals[0].sum[2]) / 3.0f; guide_pdfs[0] = guiding_bsdf_pdf(kg, state, omega_in_ris[0]); + guide_pdfs[0] *= (1.0f - bssrdf_sampling_prob); bsdf_pdfs[0] = max(0.f, bsdf_pdfs[0]); } - // assert(bsdf_pdfs[0] >= 1e-20f); - // assert(guide_pdfs[0] >= 1e-20f); // RIS1 - sample guiding float unguided_bsdf_pdfs[MAX_CLOSURE]; bsdf_eval_init(&bsdf_evals[1], CLOSURE_NONE_ID, eval); guide_pdfs[1] = guiding_bsdf_sample(kg, state, rand_guiding_bsdf_ris[1], &omega_in_ris[1]); + guide_pdfs[1] *= (1.0f - bssrdf_sampling_prob); cosines[1] = max(0.01f, fabsf(dot(sd->N, omega_in_ris[1]))); - // bsdf_pdfs[1] = _surface_shader_bsdf_eval_mis( - // kg, sd, omega_in_ris[1], nullptr, &bsdf_evals[1], 0.f, 0.f, 0); - bsdf_pdfs[1] = 0.f; bsdf_pdfs[1] = surface_shader_bsdf_eval_pdfs( kg, sd, omega_in_ris[1], &bsdf_evals[1], unguided_bsdf_pdfs, 0); label_ris[1] = label_ris[0]; @@ -633,20 +669,17 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, 3.0f; bsdf_pdfs[1] = max(0.f, bsdf_pdfs[1]); - // assert(bsdf_pdfs[1] >= 1e-20f); - // assert(guide_pdfs[1] >= 1e-20f); - int num_samples = 0; float sum_ris_pdfs = 0.f; if (avg_bsdf_evals[0] > 0.f && bsdf_pdfs[0] > 1e-10f && guide_pdfs[0] > 0.f) { # ifdef RIS_COSINE ris_pdfs[0] = (avg_bsdf_evals[0] / cosines[0] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[0]))) / + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_prob * guide_pdfs[0]))) )/ (0.5f * (bsdf_pdfs[0] + guide_pdfs[0])); //(0.5f * (bsdf_pdfs[0] + bsdf_pdfs[0])); # else ris_pdfs[0] = (avg_bsdf_evals[0] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[0]))) / + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_prob * guide_pdfs[0]))) )/ (0.5f * (bsdf_pdfs[0] + guide_pdfs[0])); # endif sum_ris_pdfs += ris_pdfs[0]; @@ -660,11 +693,11 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, if (avg_bsdf_evals[1] > 0.f && bsdf_pdfs[1] > 1e-10f && guide_pdfs[1] > 0.f) { # ifdef RIS_COSINE ris_pdfs[1] = (avg_bsdf_evals[1] / cosines[1] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[1]))) / + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_prob * guide_pdfs[1]))) ) / (0.5f * (bsdf_pdfs[1] + guide_pdfs[1])); # else ris_pdfs[1] = (avg_bsdf_evals[1] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[1]))) / + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_prob * guide_pdfs[1]))) ) / (0.5f * (bsdf_pdfs[1] + guide_pdfs[1])); # endif sum_ris_pdfs += ris_pdfs[1]; @@ -681,7 +714,6 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, return label; } - float rand_ris_select = rand_bsdf_guiding * sum_ris_pdfs; float sum_ris = 0.0f; @@ -694,21 +726,19 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, } assert(sum_ris_pdfs >= 0.f); - assert(ris_idx < 2); # ifdef RIS_COSINE guide_pdf = (avg_bsdf_evals[ris_idx] / cosines[ris_idx] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[ris_idx]))) * + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_prob * guide_pdfs[ris_idx]))) ) * (float(2) / sum_ris_pdfs); # else guide_pdf = (avg_bsdf_evals[ris_idx] * - (0.5f * ((1.0f / (pi_factor * float(M_PI))) + guide_pdfs[ris_idx]))) * + ( (((1.0f-guiding_sampling_prob) * (1.0f / (pi_factor * float(M_PI)))) + (guiding_sampling_ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs