Esempio n. 1
0
        /// <summary>
        /// Sample returns a single possible direction
        /// </summary>
        /// <param name="woL"></param>
        /// <returns></returns>
        public override (Spectrum, Vector3, double) Sample_f(Vector3 wo)
        {
            var F = fresnel.Evaluate(Utils.CosTheta(wo));

            bool entering = Utils.CosTheta(wo) > 0;
            var  etaI     = entering ? fresnel.EtaI : fresnel.EtaT;
            var  etaT     = entering ? fresnel.EtaT : fresnel.EtaI;

            var n = new Vector3(0, 0, 1);

            n = Vector3.Dot(n, wo) < 0 ? -n : n;

            var(refracted, wt) = Refract(wo, n, etaI / etaT);

            if (!refracted)
            {
                return(Spectrum.ZeroSpectrum, null, 0);
            }

            Spectrum ft = r * (1 - F.Max());

            var pdf = 1 - F.Max();

            return(ft / Utils.AbsCosTheta(wt), wt, pdf);
        }
Esempio n. 2
0
        /// <summary>
        /// Sample returns a single possible direction
        /// </summary>
        /// <param name="woL"></param>
        /// <returns></returns>
        public override (Spectrum, Vector3, double) Sample_f(Vector3 woL)
        {
            // perfect specular reflection
            Vector3  wiL = new Vector3(-woL.x, -woL.y, woL.z);
            Spectrum ft  = r * fresnel.Evaluate(Utils.CosTheta(wiL));

            return(ft / Utils.AbsCosTheta(wiL), wiL, 1);
        }
Esempio n. 3
0
        public override Spectrum f(Vector3 wo, Vector3 wi)
        {
            Vector3 wh = wo + wi;

            if (wh.z < 0.0)
            {
                wi = -wi;
                wh = -wh;
            }

            if (wh.LengthSquared() == 0.0) // epsilon ?
            {
                return(Spectrum.ZeroSpectrum);
            }

            wh = wh.Normalize();


            double  cos_phi_h   = Utils.CosPhi(wh);
            double  sin_phi_h   = Utils.SinPhi(wh);
            double  cos_theta_h = Utils.CosTheta(wh);
            double  sin_theta_h = Utils.SinTheta(wh);
            Vector3 w_hx        = new Vector3(cos_phi_h * cos_theta_h, sin_phi_h * cos_theta_h, -sin_theta_h);
            Vector3 w_hy        = new Vector3(-sin_phi_h, cos_phi_h, 0.0);
            Vector3 w_d         = new Vector3(Vector3.Dot(wi, w_hx), Vector3.Dot(wi, w_hy), Vector3.Dot(wi, wh));

            double theta_h = SphericalTheta(wh);
            double theta_d = SphericalTheta(w_d);
            double phi_d   = SphericalPhi(w_d);

            if (phi_d > Math.PI)
            {
                phi_d = phi_d - Math.PI;
            }


            // Get i.
            int theta_h_idx = ThetaHalfIndex(theta_h);
            int theta_d_idx = ThetaDiffIndex(theta_d);
            int phi_d_idx   = PhiDiffIndex(phi_d);
            int i           = phi_d_idx + (BRDF_SAMPLING_RES_PHI_D / 2) * (theta_d_idx + theta_h_idx * BRDF_SAMPLING_RES_THETA_D);

            return(Spectrum.Create(Vector <double> .Build.Dense(new[] { brdf[3 * i], brdf[3 * i + 1], brdf[3 * i + 2] })));
        }