Exemplo n.º 1
0
        public override Spectrum f(Vector3 wo, Vector3 wi)
        {
            if (!Utils.SameHemisphere(wo, wi))
            {
                return(Spectrum.ZeroSpectrum);
            }

            // Cos term
            // Adicijski izrek: cos(x +- y) = cos(x) * cos(y) -+ sin(x) * sin(y)
            double cosDiff = Utils.CosPhi(wi) * Utils.CosPhi(wo) + Utils.SinPhi(wi) * Utils.SinPhi(wo);

            // Sin and tan terms
            double sinAlpha, tanBeta;

            if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo))               // oTheta > iTheta
            {
                sinAlpha = Utils.SinTheta(wo);
                tanBeta  = Utils.SinTheta(wi) / Utils.AbsCosTheta(wi);
            }
            else                 // iTheta >= oTheta
            {
                sinAlpha = Utils.SinTheta(wi);
                tanBeta  = Utils.SinTheta(wo) / Utils.AbsCosTheta(wo);
            }

            return(kd * Utils.PiInv * (A + B * Math.Max(0, cosDiff) * sinAlpha * tanBeta));
        }
Exemplo n.º 2
0
        public override Spectrum f(Vector3 wo, Vector3 wi)
        {
            double a = 1 - ((roughness2 / 2 * (roughness2 + 0.33)));
            double b = 0.45 * roughness2 / (roughness2 + 0.09);

            double sinThetaI = Utils.SinTheta(wi);
            double sinThetaO = Utils.SinTheta(wo);

            double sinAlpha;
            double tanBeta;

            if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo))
            {
                sinAlpha = sinThetaO;
                tanBeta  = sinThetaI / Utils.AbsCosTheta(wi);
            }
            else
            {
                sinAlpha = sinThetaI;
                tanBeta  = sinThetaO / Utils.AbsCosTheta(wo);
            }
            double maxCos = 0;

            if (sinThetaI > 1e-4 && sinThetaO > 1e-4)
            {
                double dCos = Utils.CosPhi(wi) * Utils.CosPhi(wo) + Utils.SinPhi(wi) * Utils.SinPhi(wo);
                maxCos = Math.Max(0, dCos);
            }

            Spectrum nnn = (kd / Math.PI) * (a + b * maxCos * sinAlpha * tanBeta);

            return(nnn);
        }
Exemplo 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] })));
        }
Exemplo n.º 4
0
        public override Spectrum f(Vector3 wo, Vector3 wi)
        {
            // var phiWi = Phi(wi.x, wi.y);
            // var phiWo = Phi(wo.x, wo.y);
            // var thetaWi = Theta(wi.x, wi.y, wi.z);
            // var thetaWo = Theta(wo.x, wo.y, wo.z);
            //
            // var alpha = Math.Max(thetaWi, thetaWo);
            // var beta = Math.Min(thetaWi, thetaWo);
            //
            // return kd * Utils.PiInv * (a + b * Math.Max(0, Math.Cos(phiWi - phiWo))) * Math.Sin(alpha) * Math.Tan(beta);

            var sinThetaI = Utils.SinTheta(wi);
            var sinThetaO = Utils.SinTheta(wo);
            var maxCos    = 0.0;

            if (sinThetaI > 1e-4 && sinThetaO > 1e-4)
            {
                var sinPhiI = Utils.SinPhi(wi);
                var cosPhiI = Utils.CosPhi(wi);
                var sinPhiO = Utils.SinPhi(wo);
                var cosPhiO = Utils.CosPhi(wo);
                var dCos    = cosPhiI * cosPhiO + sinPhiI * sinPhiO;
                maxCos = Math.Max(0, dCos);
            }

            double sinAlpha;
            double tanBeta;

            if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo))
            {
                sinAlpha = sinThetaO;
                tanBeta  = sinThetaI / Utils.AbsCosTheta(wi);
            }
            else
            {
                sinAlpha = sinThetaI;
                tanBeta  = sinThetaO / Utils.AbsCosTheta(wo);
            }

            return(kd * Utils.PiInv * (a + b * maxCos * sinAlpha * tanBeta));
        }