Beispiel #1
0
        public RgbColor Evaluate(Vector3 outDir, Vector3 inDir, bool isOnLightSubpath)
        {
            if (!ShadingSpace.SameHemisphere(outDir, inDir))
            {
                return(RgbColor.Black);
            }

            float   cosThetaO  = ShadingSpace.AbsCosTheta(outDir);
            float   cosThetaI  = ShadingSpace.AbsCosTheta(inDir);
            Vector3 halfVector = inDir + outDir;

            // Handle degenerate cases for microfacet reflection
            if (cosThetaI == 0 || cosThetaO == 0)
            {
                return(RgbColor.Black);
            }
            if (halfVector.X == 0 && halfVector.Y == 0 && halfVector.Z == 0)
            {
                return(RgbColor.Black);
            }

            // For the Fresnel call, make sure that wh is in the same hemisphere
            // as the surface normal, so that total internal reflection is handled correctly.
            halfVector = Vector3.Normalize(halfVector);
            if (ShadingSpace.CosTheta(halfVector) < 0)
            {
                halfVector = -halfVector;
            }

            var cosine = Vector3.Dot(inDir, halfVector);
            var f      = fresnel.Evaluate(cosine);

            var nd = distribution.NormalDistribution(halfVector);
            var ms = distribution.MaskingShadowing(outDir, inDir);

            return(tint * nd * ms * f / (4 * cosThetaI * cosThetaO));
        }
Beispiel #2
0
 /// <summary>
 /// The Pdf that is used for importance sampling microfacet normals from this distribution.
 /// This usually importance samples the portion of normals that are in the hemisphere of the outgoing direction.
 /// </summary>
 /// <param name="outDir">The outgoing direction in shading space.</param>
 /// <param name="inDir">The incoming direction in shading space.</param>
 /// <returns>The pdf value.</returns>
 public float Pdf(Vector3 outDir, Vector3 normal) =>
 NormalDistribution(normal) * MaskingShadowing(outDir) * MathF.Abs(Vector3.Dot(outDir, normal))
 / ShadingSpace.AbsCosTheta(outDir);