@@ -387,45 +387,46 @@ if constexpr (std::is_same_v<decltype(VALUE),bool>) \
387387 ASSERT_VALUE (forest->addMaterial (layerH,logger),true ," Dielectric" );
388388 }
389389
390- // thindielectric
390+ // correlated thindielectric (exit through a microfacet with identical normal on the other side - no refraction possible)
391391 {
392392 const auto layerH = forest->_new <CFrontendIR::CLayer>();
393393 auto * layer = forest->deref (layerH);
394- layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Single Pane" );
394+ layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Correlated Single Pane" );
395395
396396 // do fresnel first for all to have the same one
397397 const auto fresnelH = forest->createNamedFresnel (" ThF4" );
398398 const auto * fresnel = forest->deref (fresnelH);
399399
400- auto makeIsotropicDielectric = [&]( const float roughness, const auto weightNode)-> CFrontendIR ::TypedHandle <CFrontendIR::IExprNode>
400+ const auto brdfH = forest-> _new <CFrontendIR::CMul>();
401401 {
402- const auto mulH = forest->_new <CFrontendIR::CMul>();
403- auto * mul = forest->deref (mulH);
402+ auto * mul = forest->deref (brdfH);
404403 const auto ctH = forest->_new <CFrontendIR::CCookTorrance>();
405404 {
406405 auto * ct = forest->deref (ctH);
407- ct->ndParams .getRougness ()[0 ].scale = ct->ndParams .getRougness ()[1 ].scale = roughness ;
406+ ct->ndParams .getRougness ()[0 ].scale = ct->ndParams .getRougness ()[1 ].scale = 0 . 1f ;
408407 // ignored for BRDFs, needed for BTDFs
409408 ct->orientedRealEta = fresnel->orientedRealEta ;
410409 }
411410 mul->lhs = ctH;
412- mul->rhs = weightNode;
413- return mulH;
414- };
411+ mul->rhs = fresnelH;
412+ }
413+ layer->brdfTop = brdfH;
414+ layer->brdfBottom = brdfH;
415415
416- const auto thinInfiniteScatterH = forest->_new <CFrontendIR::CThinInfiniteScatterCorrection >();
416+ const auto btdfH = forest->_new <CFrontendIR::CMul >();
417417 {
418- auto * thinInfiniteScatter = forest->deref (thinInfiniteScatterH);
419- thinInfiniteScatter->reflectance = fresnelH;
420- thinInfiniteScatter->transmittance = fresnelH;
421- // without extinction
418+ auto * mul = forest->deref (btdfH);
419+ const auto thinInfiniteScatterH = forest->_new <CFrontendIR::CThinInfiniteScatterCorrection>();
420+ {
421+ auto * thinInfiniteScatter = forest->deref (thinInfiniteScatterH);
422+ thinInfiniteScatter->reflectance = fresnelH;
423+ thinInfiniteScatter->transmittance = fresnelH;
424+ // without extinction
425+ }
426+ mul->lhs = forest->_new <CFrontendIR::CDeltaTransmission>();
427+ mul->rhs = thinInfiniteScatterH;
422428 }
423-
424- // and now the most implausible material of all!
425- // smoother on the topside and rough on the underside with a weird intermediate part
426- layer->brdfTop = makeIsotropicDielectric (0 .01f ,fresnelH);
427- layer->btdf = makeIsotropicDielectric (0 .1f ,thinInfiniteScatterH);
428- layer->brdfBottom = makeIsotropicDielectric (0 .2f ,fresnelH);
429+ layer->btdf = btdfH;
429430
430431 {
431432 auto * imagEta = forest->deref (fresnel->orientedImagEta );
@@ -493,11 +494,19 @@ if constexpr (std::is_same_v<decltype(VALUE),bool>) \
493494 midLayer->brdfTop = mulH;
494495 // no transmission in the mid-layer, the backend needs to decompose into separate front/back materials
495496 midLayer->brdfBottom = mulH;
496- midLayer->coated = rootH;
497+
498+ // can't attach a copy of the top layer because we'll have a cycle, also the BRDF needs to be on the other side
499+ const auto bottomH = forest->_new <CFrontendIR::CLayer>();
500+ {
501+ auto * bottomLayer = forest->deref (bottomH);
502+ bottomLayer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Rough Plastic Copy" );
503+ bottomLayer->brdfBottom = dielectricH;
504+ }
505+ midLayer->coated = bottomH;
497506 }
498507 topLayer->coated = diffuseH;
499508
500- ASSERT_VALUE (forest->addMaterial (rootH,logger),false ," Twosided Rough Plastic" );
509+ ASSERT_VALUE (forest->addMaterial (rootH,logger),true ," Twosided Rough Plastic" );
501510 }
502511
503512 // coated diffuse transmitter
0 commit comments