예제 #1
0
 public SpecularTransmission(float indexOfRefractionIncident, float indexOfRefractionTransmitted,
                             SampledSpectrum s = null) : base(BxDFType.Transmission | BxDFType.Specular)
 {
     _fresnel = new FresnelDielectric(indexOfRefractionIncident, indexOfRefractionTransmitted);
     _s       = s ?? SampledSpectrum.Random();
     IndexOfRefractionIncident    = indexOfRefractionIncident;
     IndexOfRefractionTransmitted = indexOfRefractionTransmitted;
 }
예제 #2
0
        public void ComputeScatteringFunctions(SurfaceInteraction inter, bool allowMultipleLobes)
        {
            inter.Bsdf = new BSDF(inter);

            if (!diffuse.IsBlack())
            {
                inter.Bsdf.Add(new LambertianReflection(diffuse));
            }

            if (!specular.IsBlack())
            {
                var fresnel      = new FresnelDielectric(1.5f, 1.0f);
                var distribution = new TrowbridgeReitzDistribution(roughness);
                inter.Bsdf.Add(new MicrofacetReflection(specular, distribution, fresnel));
            }
        }
예제 #3
0
        public RgbColor Evaluate(Vector3 outDir, Vector3 inDir, bool isOnLightSubpath)
        {
            if (ShadingSpace.SameHemisphere(outDir, inDir))
            {
                return(RgbColor.Black);                                             // transmission only
            }
            float cosThetaO = ShadingSpace.CosTheta(outDir);
            float cosThetaI = ShadingSpace.CosTheta(inDir);

            if (cosThetaI == 0 || cosThetaO == 0)
            {
                return(RgbColor.Black);
            }

            // Compute the half vector
            float   eta = ShadingSpace.CosTheta(outDir) > 0 ? (insideIOR / outsideIOR) : (outsideIOR / insideIOR);
            Vector3 wh  = Vector3.Normalize(outDir + inDir * eta);

            if (ShadingSpace.CosTheta(wh) < 0)
            {
                wh = -wh;
            }
            if (Vector3.Dot(outDir, wh) * Vector3.Dot(inDir, wh) > 0)
            {
                return(RgbColor.Black);
            }

            var F = new RgbColor(FresnelDielectric.Evaluate(Vector3.Dot(outDir, wh), outsideIOR, insideIOR));

            float sqrtDenom = Vector3.Dot(outDir, wh) + eta * Vector3.Dot(inDir, wh);
            float factor    = isOnLightSubpath ? (1 / eta) : 1;

            var numerator = distribution.NormalDistribution(wh) * distribution.MaskingShadowing(outDir, inDir);

            numerator *= eta * eta * Math.Abs(Vector3.Dot(inDir, wh)) * Math.Abs(Vector3.Dot(outDir, wh));
            numerator *= factor * factor;

            var denom = (cosThetaI * cosThetaO * sqrtDenom * sqrtDenom);

            Debug.Assert(float.IsFinite(denom));
            return((RgbColor.White - F) * transmittance * Math.Abs(numerator / denom));
        }