Fix Cycles bevel normal baking having some random incorrect pixels.

The bevel and SSS code could result in NaNs in some cases, tweak the
formulas so this can't happen.
This commit is contained in:
Brecht Van Lommel
2018-01-11 22:25:40 +01:00
parent 6b3d85fa51
commit 2dbcc17897
2 changed files with 24 additions and 23 deletions

View File

@@ -283,22 +283,23 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
object_normal_transform(kg, sd, &hit_Ng); object_normal_transform(kg, sd, &hit_Ng);
} }
/* probability densities for local frame axes */ /* Probability densities for local frame axes. */
float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng)); float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng));
float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng)); float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng));
float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng)); float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
/* multiple importance sample between 3 axes, power heuristic /* Multiple importance sample between 3 axes, power heuristic
* found to be slightly better than balance heuristic */ * found to be slightly better than balance heuristic. pdf_N
float mis_weight = power_heuristic_3(pdf_N, pdf_T, pdf_B); * in the MIS weight and denominator cancelled out. */
float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
if(ss_isect->num_hits > BSSRDF_MAX_HITS) {
w *= ss_isect->num_hits/(float)BSSRDF_MAX_HITS;
}
/* real distance to sampled point */ /* Real distance to sampled point. */
float r = len(hit_P - sd->P); float r = len(hit_P - sd->P);
/* evaluate */ /* Evaluate profiles. */
float w = mis_weight / pdf_N;
if(ss_isect->num_hits > BSSRDF_MAX_HITS)
w *= ss_isect->num_hits/(float)BSSRDF_MAX_HITS;
float3 eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w; float3 eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w;
ss_isect->weight[hit] = eval; ss_isect->weight[hit] = eval;
@@ -417,20 +418,21 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a
/* setup new shading point */ /* setup new shading point */
shader_setup_from_subsurface(kg, sd, &ss_isect.hits[0], &ray); shader_setup_from_subsurface(kg, sd, &ss_isect.hits[0], &ray);
/* probability densities for local frame axes */ /* Probability densities for local frame axes. */
float pdf_N = pick_pdf_N * fabsf(dot(disk_N, sd->Ng)); float pdf_N = pick_pdf_N * fabsf(dot(disk_N, sd->Ng));
float pdf_T = pick_pdf_T * fabsf(dot(disk_T, sd->Ng)); float pdf_T = pick_pdf_T * fabsf(dot(disk_T, sd->Ng));
float pdf_B = pick_pdf_B * fabsf(dot(disk_B, sd->Ng)); float pdf_B = pick_pdf_B * fabsf(dot(disk_B, sd->Ng));
/* multiple importance sample between 3 axes, power heuristic /* Multiple importance sample between 3 axes, power heuristic
* found to be slightly better than balance heuristic */ * found to be slightly better than balance heuristic. pdf_N
float mis_weight = power_heuristic_3(pdf_N, pdf_T, pdf_B); * in the MIS weight and denominator cancelled out. */
float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
w *= ss_isect.num_hits;
/* real distance to sampled point */ /* Real distance to sampled point. */
float r = len(sd->P - origP); float r = len(sd->P - origP);
/* evaluate */ /* Evaluate profiles. */
float w = (mis_weight * ss_isect.num_hits) / pdf_N;
eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w; eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w;
} }

View File

@@ -174,18 +174,17 @@ ccl_device_noinline float3 svm_bevel(
float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng)); float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
/* Multiple importance sample between 3 axes, power heuristic /* Multiple importance sample between 3 axes, power heuristic
* found to be slightly better than balance heuristic. */ * found to be slightly better than balance heuristic. pdf_N
float mis_weight = power_heuristic_3(pdf_N, pdf_T, pdf_B); * in the MIS weight and denominator cancelled out. */
float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
if(isect.num_hits > LOCAL_MAX_HITS) {
w *= isect.num_hits/(float)LOCAL_MAX_HITS;
}
/* Real distance to sampled point. */ /* Real distance to sampled point. */
float r = len(hit_P - sd->P); float r = len(hit_P - sd->P);
/* Compute weight. */ /* Compute weight. */
float w = mis_weight / pdf_N;
if(isect.num_hits > LOCAL_MAX_HITS) {
w *= isect.num_hits/(float)LOCAL_MAX_HITS;
}
float pdf = bssrdf_cubic_pdf(radius, 0.0f, r); float pdf = bssrdf_cubic_pdf(radius, 0.0f, r);
float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r); float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r);