[Bf-blender-cvs] [f55d6816ecd] cycles_path_guiding: Guiding: Added roughness-based MIS guiding type and fixed sss bug with RIS
Sebastian Herholz
noreply at git.blender.org
Thu Jan 26 20:15:06 CET 2023
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. @@
More information about the Bf-blender-cvs
mailing list