示例#1
0
 public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf, out RayData ray)
 {
     var wi = MC.CosineSampleHemisphere(u1, u2);
     pdf = wi.z * MathLab.INVPI;
     wi = pt.Frame.ToWorld(ref wi);
     ray = new RayData(ref pt.HitPoint, ref wi, 1e-4f, float.MaxValue);
     radiance = Le(ref wi);
 }
示例#2
0
        public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse)
        {
            float c = 1f - Vector.Dot(ref pt.IncomingDirection, ref pt.ShadingNormal);
            float Re = R0 + (1f - R0) * c * c * c * c * c;

            float P = .25f + .5f * Re;

            fs = pt.Diffuse.CloneValue().Mul(MathLab.INVPI).Mul((1f - Re) / (1f - P));
        }
示例#3
0
 public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf, out RayData ray)
 {
     var dir = -(Position - pt.HitPoint);
     var l2 = dir.Length2();
     var l = MathLab.Sqrt(l2);
     dir.Normalize();
     pdf = MC.UniformSpherePdf();
     ray = new RayData(ref pt.HitPoint, ref dir, 1e-4f, l - 1e-4f);
     radiance = power.Mul(1f / l);
     //float theta = Vector.SphericalTheta(ref dir);
     //Profile.Evaluate(Vector.SphericalPhi(ref dir) * MathLab.INVTWOPI, theta * MathLab.INVPI);
 }
示例#4
0
        public override void Sample_f(ShadePointInfo pt, float u0, float u1, float u2, out Vector vector, out float radiancePdf,
            out float pdf1, out BsdfEvent @event)
        {

            float c = 1f - Vector.Dot(ref pt.IncomingDirection, ref pt.ShadingNormal);

            float Re = R0 + (1f - R0) * c * c * c * c * c;
            float P = .25f + .5f * Re;

            if ((u2 < P && reflectionSpecularBounce))
            {//onlySpecular || 
                vector = MetalBrdf.GlossyReflection(ref pt.IncomingDirection, exponent, ref pt.ShadingNormal, u0, u1);
                pdf1 = P / Re;
                @event = BsdfEvent.Specular;
                radiancePdf = Re;
            }
            else
            {
                Vector dir = MC.CosineSampleHemisphere(u0, u1);
                pdf1 = dir.z * MathLab.INVPI;

                /*
                Vector v1, v2;
                 * 
                dir =
                
                Vector.CoordinateSystem(ref shadeN, out v1, out v2);

                dir = new Vector(
                    v1.x * dir.x + v2.x * dir.y + shadeN.x * dir.z,
                    v1.y * dir.x + v2.y * dir.y + shadeN.y * dir.z,
                    v1.z * dir.x + v2.z * dir.y + shadeN.z * dir.z);*/
                ONB fm = new ONB(ref pt.ShadingNormal);

                var wi = fm.ToWorld(ref dir);//pt.Frame

                float dp = Vector.Dot(ref pt.ShadingNormal, ref wi);
                // Using 0.0001 instead of 0.0 to cut down fireflies
                if (dp <= 0.0001f)
                {
                    pdf1 = 0f;
                }
                pdf1 /= dp;

                float iRe = 1f - Re;
                pdf1 *= (1f - P) / iRe;
                @event = BsdfEvent.Glossy | BsdfEvent.Diffuse;
                vector = wi;
                radiancePdf = iRe;

            }
        }
示例#5
0
 public override void Sample_f(ShadePointInfo point, float u0, float u1, float u2, out Vector wi, out float radiance, out float pdf, out BsdfEvent bsdfEvent)
 {
     Vector dir = MC.CosineSampleHemisphere(u0, u1);
     pdf = dir.z * MathLab.INVPI;
     bsdfEvent = BsdfEvent.Diffuse;
     wi = point.Frame.ToWorld(ref dir);
     float dp = (Normal.Dot(ref point.GeoNormal, ref wi));
     if (dp <= 0.01f)
     {
         pdf = 0f;
         bsdfEvent = BsdfEvent.Absorb;
         radiance = 0f;
     }
     else
     {
         pdf /= dp;
         radiance = MathLab.INVPI;
     }
 }
示例#6
0
 public abstract void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2,
                                      out IColorType radiance, out float pdf, out RayData ray);
示例#7
0
        public override void Sample_f(ShadePointInfo pt, float u0, float u1, float u2, 
                                      out Vector Wi, out float radiancePdf, out float pdf, out BsdfEvent @event)
        {
            Vector rayDir = -pt.IncomingDirection;
            var N = pt.GeoNormal;
            var shadeN = pt.ShadingNormal;
            var wi = new Vector();

            var N1 = N.ToVec();
            var reflDir = rayDir - (2f * (Normal.Dot(ref N, ref rayDir))) * N1;

            // Ray from outside going in ?
            bool into = ((Normal.Dot(ref N, ref shadeN)) > 0);

            float nc = n0;
            float nt = n1;
            float nnt = into ? (nc / nt) : (nt / nc);
            float ddn = (rayDir & shadeN.ToVec());
            float cos2t = 1f - nnt * nnt * (1f - ddn * ddn);
            radiancePdf = 0f;
            // Total internal reflection
            if (cos2t < 0f)
            {
                wi = reflDir;
                pdf = 1f;
                @event = BsdfEvent.Reflect | BsdfEvent.Specular;
                radiancePdf = 1f;
                Wi = wi;
                return;
            }

            float kk = (into ? 1f : -1f) * (ddn * nnt + MathLab.Sqrt((cos2t)));
            Vector nkk = kk * N1;
            Vector transDir = (nnt * rayDir - nkk).Normalize();

            float c = 1f - (into ? -ddn : (transDir & N1));

            float Re = R0 + (1f - R0) * c * c * c * c * c;
            float Tr = 1f - Re;
            float P = .25f + .5f * Re;

            if (Tr.NearEqual(0f))
            {
                if (Re.NearEqual(0f))
                {
                    pdf = 0f;
                    @event = BsdfEvent.Absorb;
                }
                else
                {
                    (wi) = reflDir;
                    pdf = 1f;
                    radiancePdf = 1f;
                    @event = BsdfEvent.Reflect | BsdfEvent.Specular;
                    Wi = wi;
                    return;
                }
            }
            else if (Re.NearEqual(0f))
            {
                (wi) = transDir;
                pdf = 1f;
                @event = BsdfEvent.Transmit | BsdfEvent.Specular;
                radiancePdf = 1.0f;                
            }
            else if (u0 < P)
            {

                (wi) = reflDir;
                pdf = P / Re;
                radiancePdf = 1f;
                @event = BsdfEvent.Reflect | BsdfEvent.Specular;
            }
            else
            {

                (wi) = transDir;
                pdf = (1f - P) / Tr;
                @event = BsdfEvent.Transmit | BsdfEvent.Specular;
                radiancePdf = 1.0f;
            }
            Wi = wi;
        }
示例#8
0
 public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse)
 {
     throw new NotImplementedException();
 }
示例#9
0
 public BrdfBase GetBrdf(ShadePointInfo point, float u0, out float pdf)
 {
     pdf = 1f;
     return this.brdf;
 }
示例#10
0
 public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse)
 {
     fs = pt.Diffuse.Mul(MathLab.INVPI);
 }
示例#11
0
        public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, 
                                            out IColorType radiance, out float pdf,out RayData ray)
        {
            int tries = 0;

#if VERBOSE
            try
            {
#endif
            ray = new RayData() {Org = pt.HitPoint};
            Point samplePoint;
            float b0, b1, b2;
            int maxTries = 1;
        startTry:

            var index = Math.Max(0, Math.Min(triangleSampleData.Length - 1, (int)(u0 * (mesh.EndTriangle - mesh.StartTriangle))));
            Sample(ref scene.Triangles[mesh.StartTriangle + index], scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2);

            var u = b0;
            var v = b1;

            var triangleNormal = triangleSampleData[index].Item2;
            var area = triangleSampleData[index].Item1;
            //tri.AreaV(scene.Vertices);
            //var sampleN = TriangleNormal;
            //var N = n;

            Vector wi = samplePoint - pt.HitPoint;
            //wi.Normalize();
            float distanceSquared = wi.Length2();
            var distance = MathLab.Sqrt(distanceSquared);
            wi /= distance;

            var nw = -wi;
            float sampleNdotMinusWi = Normal.Dot(ref triangleNormal, ref nw);
            float NdotWi = Normal.Dot(ref pt.GeoNormal, ref wi);
            if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f))
            {
                tries++;
                if (tries > maxTries)
                {
                    pdf = 0f;
                    radiance = ColorManager.Instance.Zero();
                    return;
                }

                goto startTry;
            }

            pdf =
                //((1f / area) * distanceSquared / sampleNdotMinusWi) * (1f / mesh.TrianglesCount) * (1f / Math.Max(1, tries + 1));
                (distanceSquared / (sampleNdotMinusWi * area)) * 1f / mesh.TrianglesCount * (1f / Math.Max(1, tries + 1));




            // Using 0.01 instead of 0.0 to cut down fireflies
            if (pdf <= 0.01f)
            {
                pdf = 0f;
                radiance = ColorManager.Instance.Zero();

                return;
            }
            float lp;
            radiance = Material.GetEmittance(u, v, out lp);
            ray.Dir = wi;
            //, MathLab.RAY_EPSILON, distance - MathLab.RAY_EPSILON);
#if VERBOSE
            }
            catch (Exception ex)
            {
                Tracer.TraceLine(ex.Message + ex.StackTrace);
                Tracer.TraceLine("Triangle data offset " + (mesh.StartTriangle).ToString() + "of " + triangleSampleData.Length);
                throw ex;
            }
#endif
        }