diff --git a/pxr/imaging/plugin/hdEmbree/mesh.h b/pxr/imaging/plugin/hdEmbree/mesh.h index bbb006302f..2d1ff9a257 100644 --- a/pxr/imaging/plugin/hdEmbree/mesh.h +++ b/pxr/imaging/plugin/hdEmbree/mesh.h @@ -99,6 +99,11 @@ class HdEmbreeMesh final : public HdMesh { /// embree state. virtual void Finalize(HdRenderParam *renderParam) override; + bool EmbreeMeshIsDoubleSided() const + { + return _doubleSided; + } + protected: // Initialize the given representation of this Rprim. // This is called prior to syncing the prim, the first time the repr diff --git a/pxr/imaging/plugin/hdEmbree/renderer.cpp b/pxr/imaging/plugin/hdEmbree/renderer.cpp index e5b50f29b0..276110c405 100644 --- a/pxr/imaging/plugin/hdEmbree/renderer.cpp +++ b/pxr/imaging/plugin/hdEmbree/renderer.cpp @@ -1657,8 +1657,23 @@ HdEmbreeRenderer::_ComputeLighting( float vis = _Visibility(position, ls.wI, ls.dist * 0.99f); // Add exitant luminance + float cosOffNormal = GfDot(ls.wI, normal); + if (cosOffNormal < 0.0f) { + bool doubleSided = false; + HdEmbreeMesh *mesh = + dynamic_cast(prototypeContext->rprim); + if (mesh) { + doubleSided = mesh->EmbreeMeshIsDoubleSided(); + } + + if (doubleSided) { + cosOffNormal *= -1.0f; + } else { + cosOffNormal = 0.0f; + } + } finalColor += ls.Li - * _DotZeroClip(ls.wI, normal) + * cosOffNormal * brdf * vis * ls.invPdfW;