@@ -137,12 +137,12 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
137
137
const float monochromeEta = dot (throughputCIE_Y,BSDFNode_getEta(bsdf)[0 ])/ (throughputCIE_Y.r+ throughputCIE_Y.g+ throughputCIE_Y.b);
138
138
139
139
// do NEE
140
- const float neeProbability = 1.0 ; // BSDFNode_getMISWeight(bsdf);
141
- const float neeProbability2 = neeProbability * neeProbability ;
142
- if (true )
140
+ const float neeProbability = BSDFNode_getMISWeight(bsdf);
141
+ float rcpChoiceProb ;
142
+ if (! nbl_glsl_partitionRandVariable(neeProbability,epsilon[ 0 ].z,rcpChoiceProb) )
143
143
{
144
144
vec3 neeContrib; float lightPdf, t;
145
- nbl_glsl_LightSample _sample = nbl_glsl_light_generate_and_remainder_and_pdf(neeContrib,lightPdf,t,intersection,interaction,epsilon[1 ],depth);
145
+ nbl_glsl_LightSample _sample = nbl_glsl_light_generate_and_remainder_and_pdf(neeContrib,lightPdf,t,intersection,interaction,epsilon[0 ],depth);
146
146
// We don't allow non watertight transmitters in this renderer
147
147
bool validPath = _sample.NdotL> 0.0 ;
148
148
// but if we allowed non-watertight transmitters (single water surface), it would make sense just to apply this line by itself
@@ -152,7 +152,8 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
152
152
{
153
153
float bsdfPdf;
154
154
neeContrib *= nbl_glsl_bsdf_cos_remainder_and_pdf(bsdfPdf,_sample,interaction,bsdf,monochromeEta,_cache)* throughput;
155
- neeContrib /= bsdfPdf/ (lightPdf* lightPdf)+ neeProbability2/ bsdfPdf; // MIS weight
155
+ const float oc = bsdfPdf* rcpChoiceProb;
156
+ neeContrib /= 1.0 / oc+ oc/ (lightPdf* lightPdf); // MIS weight
156
157
if (bsdfPdf< FLT_MAX && getLuma(neeContrib)> lumaContributionThreshold && traceRay(t,intersection+ _sample.L* t* getStartTolerance(depth),_sample.L)==-1 )
157
158
ray._payload.accumulation += neeContrib;
158
159
}
@@ -162,7 +163,7 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
162
163
float bsdfPdf; vec3 bsdfSampleL;
163
164
{
164
165
nbl_glsl_AnisotropicMicrofacetCache _cache;
165
- nbl_glsl_LightSample _sample = nbl_glsl_bsdf_cos_generate(interaction,epsilon[0 ],bsdf,monochromeEta,_cache);
166
+ nbl_glsl_LightSample _sample = nbl_glsl_bsdf_cos_generate(interaction,epsilon[1 ],bsdf,monochromeEta,_cache);
166
167
// the value of the bsdf divided by the probability of the sample being generated
167
168
throughput *= nbl_glsl_bsdf_cos_remainder_and_pdf(bsdfPdf,_sample,interaction,bsdf,monochromeEta,_cache);
168
169
//
@@ -174,7 +175,8 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
174
175
if (bsdfPdf> bsdfPdfThreshold && getLuma(throughput)> lumaThroughputThreshold)
175
176
{
176
177
ray._payload.throughput = throughput;
177
- ray._payload.otherTechniqueHeuristic = neeProbability2/ (bsdfPdf* bsdfPdf); // numerically stable, don't touch
178
+ ray._payload.otherTechniqueHeuristic = neeProbability/ bsdfPdf; // numerically stable, don't touch
179
+ ray._payload.otherTechniqueHeuristic *= ray._payload.otherTechniqueHeuristic;
178
180
179
181
// trace new ray
180
182
ray._immutable.origin = intersection+ bsdfSampleL* (1.0 /* kSceneSize*/ )* getStartTolerance(depth);
@@ -183,7 +185,4 @@ bool closestHitProgram(in uint depth, in uint _sample, inout Ray_t ray, inout nb
183
185
}
184
186
}
185
187
return false;
186
- }
187
- #if 0
188
- const bool doNEE = nbl_glsl_partitionRandVariable(bsdfGeneratorProbability,epsilon[0 ].z,rcpChoiceProb);
189
- #endif
188
+ }
0 commit comments