Skip to content

Commit 3253b6f

Browse files
author
devsh
committed
fix NEE_ONLY setting
1 parent 24f952d commit 3253b6f

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

30_ComputeShaderPathTracer/app_resources/common.glsl

+32-23
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
596596
if (BSDFNode_isNotDiffuse(bsdf))
597597
{
598598
if (ray._payload.hasDiffuse)
599-
return true;
599+
return false;
600600
}
601601
else
602602
ray._payload.hasDiffuse = true;
@@ -613,47 +613,55 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
613613
const float monochromeEta = dot(throughputCIE_Y,BSDFNode_getEta(bsdf)[0])/(throughputCIE_Y.r+throughputCIE_Y.g+throughputCIE_Y.b);
614614

615615
// do NEE
616-
const float neeProbability = 1.0;// BSDFNode_getNEEProb(bsdf);
616+
#ifndef NEE_ONLY
617+
// to turn off NEE, set this to 0
618+
const float neeProbability = BSDFNode_getNEEProb(bsdf);
617619
float rcpChoiceProb;
618620
if (!nbl_glsl_partitionRandVariable(neeProbability,epsilon[0].z,rcpChoiceProb))
619621
{
622+
#endif
620623
vec3 neeContrib; float lightPdf, t;
621624
nbl_glsl_LightSample nee_sample = nbl_glsl_light_generate_and_remainder_and_pdf(
622625
neeContrib, lightPdf, t,
623626
intersection, interaction,
624627
isBSDF, epsilon[0], depth
625628
);
626-
// We don't allow non watertight transmitters in this renderer
629+
// We don't allow non watertight transmitters in this renderer & scene, one cannot reach a light from the backface (optimization)
627630
bool validPath = nee_sample.NdotL>nbl_glsl_FLT_MIN;
628631
// but if we allowed non-watertight transmitters (single water surface), it would make sense just to apply this line by itself
629632
nbl_glsl_AnisotropicMicrofacetCache _cache;
630633
validPath = validPath && nbl_glsl_calcAnisotropicMicrofacetCache(_cache, interaction, nee_sample, monochromeEta);
634+
// infinite PDF would mean a point light or a thin line, but our lights have finite radiance per steradian (area lights)
631635
if (lightPdf<nbl_glsl_FLT_MAX)
632636
{
633-
if (any(isnan(nee_sample.L)))
634-
ray._payload.accumulation += vec3(1000.f,0.f,0.f);
635-
else
636-
if (all(equal(vec3(69.f),nee_sample.L)))
637-
ray._payload.accumulation += vec3(0.f,1000.f,0.f);
638-
else
639-
if (validPath)
640-
{
641-
float bsdfPdf;
642-
neeContrib *= nbl_glsl_bsdf_cos_remainder_and_pdf(bsdfPdf,nee_sample,interaction,bsdf,monochromeEta,_cache)*throughput;
643-
const float otherGenOverChoice = bsdfPdf*rcpChoiceProb;
637+
// debug coloring
638+
if (any(isnan(nee_sample.L)))
639+
ray._payload.accumulation += vec3(1000.f,0.f,0.f);
640+
else
641+
if (all(equal(vec3(69.f),nee_sample.L)))
642+
ray._payload.accumulation += vec3(0.f,1000.f,0.f);
643+
else
644+
if (validPath) // normally one would check for a valid path first, because zero solid angle light is less likely
645+
{
646+
float bsdfPdf;
647+
// this is kinda the wrong fuction to use, we should use eval_and_pdf instead (because eval returns 0 for directions accidentally coincident with dirac delta)
648+
neeContrib *= nbl_glsl_bsdf_cos_remainder_and_pdf(bsdfPdf,nee_sample,interaction,bsdf,monochromeEta,_cache)*throughput;
649+
// this is why we need to multiply `bsdfPdf` back in, and why we have a check for the BxDF PDF not being INF
644650
#ifndef NEE_ONLY
645-
const float otherGenOverLightAndChoice = otherGenOverChoice/lightPdf;
646-
neeContrib *= otherGenOverChoice/(1.f+otherGenOverLightAndChoice*otherGenOverLightAndChoice); // MIS weight
651+
const float otherGenOverChoice = bsdfPdf*rcpChoiceProb;
652+
const float otherGenOverLightAndChoice = otherGenOverChoice/lightPdf;
653+
// MIS weight (TODO: is it correct? should `otherGenOverLightAndChoice` contain the `rcpChoiceProb` ?)
654+
neeContrib *= otherGenOverChoice/(1.f+otherGenOverLightAndChoice*otherGenOverLightAndChoice);
647655
#else
648-
neeContrib *= otherGenOverChoice;
656+
neeContrib *= bsdfPdf;
649657
#endif
650-
if (bsdfPdf<nbl_glsl_FLT_MAX && getLuma(neeContrib)>lumaContributionThreshold && traceRay(t,intersection+nee_sample.L*t*getStartTolerance(depth),nee_sample.L)==-1)
651-
ray._payload.accumulation += neeContrib;
652-
}}
658+
if (bsdfPdf<nbl_glsl_FLT_MAX && getLuma(neeContrib)>lumaContributionThreshold && traceRay(t,intersection+nee_sample.L*t*getStartTolerance(depth),nee_sample.L)==-1)
659+
ray._payload.accumulation += neeContrib;
660+
}
661+
}
662+
#ifndef NEE_ONLY
653663
}
654-
#if NEE_ONLY
655-
return false;
656-
#endif
664+
657665
// sample BSDF
658666
float bsdfPdf; vec3 bsdfSampleL;
659667
{
@@ -682,6 +690,7 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
682690
#endif
683691
return true;
684692
}
693+
#endif
685694
}
686695
return false;
687696
}

0 commit comments

Comments
 (0)