Exemplo n.º 1
0
        float ComputeOneDir(Vector3 outDir, Vector3 inDir)
        {
            // Compute the half vector
            float   eta = ShadingSpace.CosTheta(outDir) > 0 ? (insideIOR / outsideIOR) : (outsideIOR / insideIOR);
            Vector3 wh  = outDir + inDir * eta;

            if (wh == Vector3.Zero)
            {
                return(0);                    // Prevent NaN if outDir and inDir exactly align
            }
            wh = Vector3.Normalize(wh);

            if (Vector3.Dot(outDir, wh) * Vector3.Dot(inDir, wh) > 0)
            {
                return(0);
            }

            // Compute change of variables _dwh\_dinDir_ for microfacet transmission
            float sqrtDenom = Vector3.Dot(outDir, wh) + eta * Vector3.Dot(inDir, wh);

            if (sqrtDenom == 0)
            {
                return(0);                // Prevent NaN in corner case
            }
            float dwh_dinDir = Math.Abs((eta * eta * Vector3.Dot(inDir, wh)) / (sqrtDenom * sqrtDenom));

            float result = distribution.Pdf(outDir, wh) * dwh_dinDir;

            Debug.Assert(float.IsFinite(result));
            return(result);
        }
Exemplo n.º 2
0
        public (float, float) Pdf(Vector3 outDir, Vector3 inDir, bool isOnLightSubpath)
        {
            if (!ShadingSpace.SameHemisphere(outDir, inDir))
            {
                return(0, 0);
            }

            var halfVector = outDir + inDir;

            // catch NaN causing corner cases
            if (halfVector == Vector3.Zero)
            {
                return(0, 0);
            }

            halfVector = Vector3.Normalize(halfVector);
            var pdfForward = distribution.Pdf(outDir, halfVector) / Math.Abs(4 * Vector3.Dot(outDir, halfVector));
            var pdfReverse = distribution.Pdf(inDir, halfVector) / Math.Abs(4 * Vector3.Dot(inDir, halfVector));

            return(pdfForward, pdfReverse);
        }