示例#1
0
        public override void InitPath(IPathProcessor buffer)
        {
            //Choose lightsource
            //Sample it
            base.InitPath(buffer);
            this.Sample = new Sample(pathIntegrator.Sampler);
            this.RayIndex = -1;
            float lspdf;

            int li = scene.SampleLights(this.Sample.GetLazyValue(), out lspdf);
            RayData ray;

            var ls = new LightSample();
            bool done = false;
            while (!done)
            {
                scene.Lights[li].EvaluatePhoton(
                    scene,
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    out ls);

                done = ls.Pdf > 0f;

            }

            this.pathWeight = 10000 /(ls.Pdf * lspdf);
            ls.Spectrum.Mul(pathWeight);
            this.ThroughtPut = new RgbSpectrum(ls.Spectrum.ToArray());
            this.PathRay = ls.LightRay;
        }
示例#2
0
        public void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample[] result, float ltProb = 0f)
        {

            switch (scene.LightSamplingStrategy)
            {
                case LightSamplingStrategy.UniformOneLight:
                    if (result == null)
                        result = new LightSample[scene.ShadowRaysPerSample];
                    for (int i = 0; i < scene.ShadowRaysPerSample; i++)
                    {
                        int currentLightIndex = scene.SampleLights(ltProb <= 0f ? rnd.NextFloat() : ltProb);
                        var light = scene.Lights[currentLightIndex];
                        var ls = result[i]??new LightSample();
                        ls.LightIndex = currentLightIndex;
                        light.EvaluateShadow(ref point, ref n, u0, u1, u2, ref ls);
                        //ls.Pdf *= (scene.ShadowRaysPerSample);
                        result[i] = ls;
                    }
                    break;
                case LightSamplingStrategy.UniformAllLights:
                    {
                        var sm = new List<LightSample>();

                        foreach (var light in scene.Lights)
                        {
                            var ls = new LightSample();
                            light.EvaluateShadow(ref point, ref n, u0, u1, u2, ref ls);
                            if (ls.Pdf > 0f)
                                sm.Add(ls);
                        }
                        result = sm.ToArray();
                    }
                    break;
            }
        }
示例#3
0
        public override void InitPath(IPathProcessor buffer)
        {
            base.InitPath(buffer);
            scene = pathIntegrator.Scene;

            this.Sample = new Sample(pathIntegrator.Sampler);
            this.RayIndex = -1;
            float lspdf;

            int li = scene.SampleLights(this.Sample.GetLazyValue(), out lspdf);
            var ls = new LightSample();
            bool done = false;
            while (!done)
            {
                scene.Lights[li].EvaluatePhoton(
                    scene,
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    Sample.GetLazyValue(),
                    out ls);

                done = ls.Pdf > 0f;

            }

            var pathWeight =  (ls.Pdf *  lspdf);

            this.ThroughtPut = ((RgbSpectrum)(ls.Spectrum) / pathWeight);
            this.PathRay = ls.LightRay;
        }
示例#4
0
        private IColorType SampleProfile(ref LightSample ls, EmissionProfile profile)
        {
            if (profile.ProfileMode == ProfileMode.EmissionValue)
            {
                return ColorManager.Instance.Convert(profile.EmissionSpectra, SpectrumType.Illuminant);
            }

            var c = (RgbSpectrum)profile.EmissionTexture.Sample(ls.U, ls.V);
            return ColorManager.Instance.Convert(ref c);
        }
示例#5
0
        public void EvaluatePhoton(IRayEngineScene scene, float u0, float u1, float u2, float u3, float u4, out LightSample result)
        {
            result = new LightSample();

            Vector dir = MC.UniformSampleSphere(u0, u1);

            result.LightRay = new RayData(ref Position, ref dir, 1e-4f, 1e4f);

            result.Pdf = MathLab.INV4PI;

            result.Spectrum = (Power * MathLab.M_PI * 4f);
        }
示例#6
0
        public virtual void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample result)
        {
#if VERBOSE
            try{
#endif
            if (result == null)
                result = new LightSample();

            if (true)
            {
                var wi = MC.CosineSampleHemisphere(u1, u2);

                Vector v1, v2;
                Vector.CoordinateSystem(ref n, out v1, out v2);
                //Console.WriteLine("Should share frame(ONB) with bsdf somehow");

                wi = new Vector(
                    v1.x*wi.x + v2.x*wi.y + n.x*wi.z,
                    v1.y*wi.x + v2.y*wi.y + n.y*wi.z,
                    v1.z*wi.x + v2.z*wi.y + n.z*wi.z).Normalize();

                result.LightRay = new RayData(ref point, ref wi, 1e-4f, float.MaxValue);
                result.Distance = 1e4f;
                result.Spectrum = Le(ref wi);
                
                result.Pdf = Math.Abs(wi.z * MathLab.INVPI);

                //var i = ((RgbSpectrumInfo) result.Spectrum).y();
                //result.Pdf *= i;

            }
            else
            {
                Vector wi = MC.UniformSampleSphere(u0, u1);

                result.LightRay = new RayData(ref point, ref wi, 1e-4f, float.MaxValue);
                result.Pdf = 1f / (4f * MathLab.M_PI);
                result.Spectrum =  Le(ref wi);

                //var i = ((RgbSpectrumInfo)result.Spectrum).y();
                //result.Pdf *= i;
            }
#if VERBOSE
            }catch(Exception ex) {
                Tracer.TraceLine(ex.Message);
                Tracer.TraceLine(ex.StackTrace);
                throw;
            }
#endif
        }
示例#7
0
        public void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample[] result, float ltProb = 0f)
        {

            switch (scene.LightSamplingStrategy)
            {
                case LightSamplingStrategy.UniformOneLight:
                    if (result == null)
                        result = new LightSample[scene.ShadowRaysPerSample];
                    for (int i = 0; i < scene.ShadowRaysPerSample; i++)
                    {
                        int currentLightIndex = scene.SampleLights(ltProb <= 0f ? rnd.NextFloat() : ltProb);
                        var light = scene.Lights[currentLightIndex];
                        var ls = result[i] ?? new LightSample() { LightRay = new RayData() { Org = point } };
                        ls.LightIndex = currentLightIndex;
                        light.SampleSpatialDirect(ref point, ref n, u0, u1, u2, ref ls);
                        ls.LightRay.maxT = ls.Distance;
                        if (light is BaseInfiniteLight)
                        {
                            ls.Color = ColorManager.Instance.Convert(light.Le(ref ls.LightRay.Dir).ToArray());
                        }
                        else
                        {
                            ls.Color = this.SampleProfile(ref ls, light.Profile);
                        }
                        //ls.Pdf *= (scene.ShadowRaysPerSample);
                        result[i] = ls;
                    }
                    break;
                case LightSamplingStrategy.UniformAllLights:
                    {
                        var sm = new List<LightSample>();

                        foreach (var light in scene.Lights)
                        {
                            var ls = new LightSample();
                            light.EvaluateShadow(ref point, ref n, u0, u1, u2, ref ls);
                            if (ls.Pdf > 0f)
                                sm.Add(ls);
                        }
                        result = sm.ToArray();
                    }
                    throw new NotImplementedException("UniformAllLights not implemented");
                    break;
            }
        }
示例#8
0
 public void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample result)
 {
     if (result == null)
         result = new LightSample();
     var dir = -(Position - point);
     var l2 = dir.Length2();
     var l = MathLab.Sqrt(l2);
     dir.Normalize();
     result.Pdf = MC.UniformSpherePdf();
     result.LightRay = new RayData(ref point, ref dir, 1e-4f, l - 1e-4f);
     result.Distance = l;
     float theta = Vector.SphericalTheta(ref dir);
     var i = Profile.Evaluate(Vector.SphericalPhi(ref dir) * MathLab.INVTWOPI, theta * MathLab.INVPI);
     i.Div(l);
     var p = (ISpectrum) Power;
     i.Mul(ref p);
     result.Spectrum = i;
 }
示例#9
0
 public override void InitPath(IPathProcessor buffer)
 {
     base.InitPath(buffer);
     this.scene = pathIntegrator.Scene;
     this.Radiance = new RgbSpectrum(0f);
     this.Throughput = new RgbSpectrum(1f);
     this.PathState = PathTracerPathState.EyeVertex;
     if (this.secRays == null)
         this.secRays = new ShadowRayInfo[scene.ShadowRayCount];
     this.Sample = pathIntegrator.Sampler.GetSample(null);
     pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay);
     this.RayIndex = -1;
     this.pathWeight = 1.0f;
     this.lastPdfW = 1.0f;
     this.tracedShadowRayCount = 0;
     this.depth = 0;
     this.specularBounce = true;
     if (ls == null)
         ls = new LightSample();
 }
示例#10
0
        public void EvaluateShadow(BaseBxdf bsdfSample,float u0, float u1, float u2, ref LightSample[] result, float ltProb = 0f)
        {

            switch (scene.LightSamplingStrategy)
            {
                case LightSamplingStrategy.UniformOneLight:
                    if (result == null)
                        result = new LightSample[scene.ShadowRaysPerSample];
                    for (int i = 0; i < scene.ShadowRaysPerSample; i++)
                    {
                        int currentLightIndex = scene.SampleLights(ltProb <= 0f ? rnd.NextFloat() : ltProb);
                        var lt0 = scene.Lights[currentLightIndex] as INewLight;
                        var lt1 = scene.Lights[currentLightIndex] as ILight;
                        
                        var ls = result[i] ?? new LightSample();
                        ls.LightIndex = currentLightIndex;
                        if (lt0 == null)
                            lt1.EvaluateShadow(ref bsdfSample.HitPoint.HitPoint, ref bsdfSample.HitPoint.GeoNormal, u0, u1, u2, ref ls);
                        else 
                            lt0.EvaluateShadow(bsdfSample, u0, u1, u2, ref ls);
                        //ls.Pdf *= (scene.ShadowRaysPerSample);
                        result[i] = ls;
                    }
                    break;
                case LightSamplingStrategy.UniformAllLights:
                    {
                        var sm = new List<LightSample>();

                        foreach (var light in scene.Lights.Cast<INewLight>())
                        {
                            var ls = new LightSample();
                            light.EvaluateShadow(bsdfSample, u0, u1, u2, ref ls);
                            if (ls.Pdf > 0f)
                                sm.Add(ls);
                        }
                        result = sm.ToArray();
                    }
                    break;
            }
        }
示例#11
0
        public void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample result)
        {
            if (result == null)
                result = new LightSample();

            var l = Position - (point + MC.UniformSampleSphere(u0, u1) * Radius);	// vector to random point on source
            var Dist = l.Length;		// distance to light source


            result.Distance = Dist;
            result.Pdf = MC.UniformSpherePdf();
            result.LightRay = new RayData(point, l/Dist, 1e-4f, Dist - 1e-4f);
//            result.Spectrum = GlobalConfiguration.Instance.SpectralRendering ? (ISpectrum) (Spectra / Dist) : (Power / Dist);

            float theta = Vector.SphericalTheta(ref result.LightRay.Dir);

            var i = Profile.Evaluate(Vector.SphericalPhi(ref result.LightRay.Dir) * MathLab.INVTWOPI, theta * MathLab.INVPI);
            i.Div(Dist);
            var p = (ISpectrum)Power;
            i.Mul(ref p);
            result.Spectrum = i;
        }
示例#12
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
#if VERBOSE
            try
            {
#endif
                base.Advance(rayBuffer, consumer);



                var rayHit = new RayHit();

                Vector wo = -PathRay.Dir;

                switch (PathState)
                {
                    case PathTracerPathState.EyeVertex:
                        float t, t1;
                        if (scene.VolumeIntegrator != null && scene.VolumeIntegrator.GetBounds().Intersect(PathRay, out t, out t1))
                        {
                            rayHit = rayBuffer.rayHits[RayIndex];

                            // Use Russian Roulette to check if I have to do participating media computation or not
                            if (Sample.GetLazyValue() <= scene.VolumeIntegrator.GetRRProbability())
                            {
                                RayData volumeRay = new RayData(ref PathRay.Org, ref PathRay.Dir, 0f,
                                                                rayHit.Miss() ? 1e10f : rayHit.Distance);
                                scene.VolumeIntegrator.GenerateLiRays(scene, Sample, ref volumeRay, volumeComp);
                                Radiance += volumeComp.GetEmittedLight();

                                if (volumeComp.GetRayCount() > 0)
                                {
                                    // Do the EYE_VERTEX_VOLUME_STEP
                                    PathState = PathTracerPathState.EyeVolume;
                                    eyeHit = (rayBuffer.rayHits[RayIndex]);
                                    return;
                                }
                            }
                        }
                        else
                        {
                            rayHit = rayBuffer.rayHits[RayIndex];
                        }
                        break;
                    case PathTracerPathState.NextVertex:
                        rayHit = rayBuffer.rayHits[RayIndex];
                        break;
                    case PathTracerPathState.EyeVolume:
                        Radiance += Throughput * volumeComp.CollectResults(rayBuffer) /
                                    scene.VolumeIntegrator.GetRRProbability();
                        rayHit = eyeHit;
                        break;
                }

                if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                    (tracedShadowRayCount > 0))
                {
                    for (int i = 0; i < tracedShadowRayCount; ++i)
                    {
                        RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex];
                        RgbSpectrum attenuation;
                        if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                        {
                            //                            Radiance.MADD()
                            Radiance += attenuation * ((secRays[i].color) / secRays[i].pdf);
                            pathWeight *= secRays[i].pdf;
                        }
                    }
                    tracedShadowRayCount = 0;
                    if (PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                    {
                        Splat(consumer);
                        return;
                    }
                }

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                {
                    if (specularBounce && missed)
                    {
                        Radiance += this.SampleEnvironment(-PathRay.Dir) * Throughput;
                    }
                    Splat(consumer);
                    return;
                }

                // Something was hit
                if (_hitInfo == null)
                    _hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                else
                {
                    SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref _hitInfo);
                }
                var currentTriangleIndex = (int)rayHit.Index;

                //If Hit light)
                if (_hitInfo.IsLight)
                {
                    if (specularBounce)
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt == null)
                        {
                            goto errro;
                        }
                        var le = (RgbSpectrum)(RgbSpectrumInfo)(lt.Le(ref wo));
                        Radiance += Throughput * le;
                    }
                    Splat(consumer);
                    return;
                }
            @errro:

                var hitPoint = PathRay.Point(rayHit.Distance);

                tracedShadowRayCount = 0;
                if (_hitInfo.MMaterial.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = Throughput * _hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRaysPerSample; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint, ref _hitInfo.ShadingNormal, Sample.GetLazyValue(),
                                             Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        secRays[tracedShadowRayCount].color = ls.Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum)(RgbSpectrumInfo)ls.Spectrum : (RgbSpectrum)ls.Spectrum;
                        secRays[tracedShadowRayCount].pdf = ls.Pdf;
                        secRays[tracedShadowRayCount].shadowRay = ls.LightRay;

                        RgbSpectrum fs;
                        _hitInfo.MMaterial.f(
                            ref secRays[tracedShadowRayCount].shadowRay.Dir,
                            ref wo, ref _hitInfo.ShadingNormal, ref Throughput, out fs);
                        Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir;
                        secRays[tracedShadowRayCount].color *= lightTroughtput *
                                                               Vector.AbsDot(ref _hitInfo.ShadingNormal, ref lwi) *
                                                               fs;
                        if (!secRays[tracedShadowRayCount].color.IsBlack())
                        {
                            secRays[tracedShadowRayCount].pdf *= lightStrategyPdf;
                            tracedShadowRayCount++;
                        }
                    }
                }

                float fPdf;
                Vector wi;

                RgbSpectrum f = _hitInfo.MMaterial.Sample_f(ref wo, out wi, ref _hitInfo.Normal, ref _hitInfo.ShadingNormal, ref Throughput,
                                                          Sample.GetLazyValue(), Sample.GetLazyValue(),
                                                          Sample.GetLazyValue(), ref _hitInfo.TextureData,
                                                          out fPdf, out specularBounce);

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);
                    }
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= f / fPdf;

                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {
                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    else
                    {
                        if (tracedShadowRayCount > 0)
                            PathState = PathTracerPathState.ShadowRaysOnly;
                        else
                        {
                            Splat(consumer);
                        }

                        return;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = PathTracerPathState.NextVertex;

#if VERBOSE

            }
            catch (Exception ex)
            {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);
                throw;
            }
#endif
        }
示例#13
0
        public void SampleSpatialDirect(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample ls)
        {
            var wi = MC.CosineSampleHemisphere(u1, u2);

            Vector v1, v2;
            Vector.CoordinateSystem(ref n, out v1, out v2);
            //Console.WriteLine("Should share frame(ONB) with bsdf somehow");

            ls.LightRay.Dir = new Vector(
                v1.x * wi.x + v2.x * wi.y + n.x * wi.z,
                v1.y * wi.x + v2.y * wi.y + n.y * wi.z,
                v1.z * wi.x + v2.z * wi.y + n.z * wi.z).Normalize();

            ls.Distance = 1e4f;
            ls.Pdf = wi.z * MathLab.INVPI;
        }
示例#14
0
        public void SampleSpatialDirect(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample ls)
        {
            var l = Position - (point + MC.UniformSampleSphere(u0, u1) * Radius);	// vector to random point on source
            ls.Distance = l.Length;		// distance to light source

            ls.Pdf = MC.UniformSpherePdf();
            ls.LightRay.Dir = l / ls.Distance;

        }
示例#15
0
 public void SampleSpatialDirect(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample ls)
 {
     var dir = -(Position - point);
     var l2 = dir.Length2();
     var l = MathLab.Sqrt(l2);
     dir.Normalize();
     ls.Pdf = MC.UniformSpherePdf();
     ls.Distance = l;
     float theta = Vector.SphericalTheta(ref dir);
     var i = Profile.Evaluate(Vector.SphericalPhi(ref dir) * MathLab.INVTWOPI, theta * MathLab.INVPI);
     i.Div(l);
 }
示例#16
0
 public void EvaluatePhoton(float u0, float u1, float u2, float u3, float u4,
                            out LightSample[] result, float ltProb = 0f)
 {
     throw new NotImplementedException();
 }
示例#17
0
        public Color PathTrace(Ray ray, HitRecord record, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            float q          = 0f;
            int   depth      = 0;
            Color pixelColor = new Color(0, 0, 0);
            Color alpha      = new Color(1, 1, 1);

            bool isGeneratedFromRefraction = false;

            while (depth < Constants.MaximalPathLength)
            {
                if (record == null)
                {
                    return(pixelColor);
                }
                //Select one light at random
                ILight light = Randomizer.PickRandomLight(lights);
                //Sample that light
                light.Sample(record, lightSample);

                if (isGeneratedFromRefraction && record.HitObject.Light != null)
                {
                    isGeneratedFromRefraction = false;
                    pixelColor.Append(record.HitObject.Light.LightColor);
                }

                pixelColor.Append(alpha.Mult(Shade(record, lightSample)).Div(lightSample.Pdf));

                //Break with Russian roulette
                if (depth > 2)
                {
                    q = 0.5f;
                    if (random.NextDouble() <= q)
                    {
                        return(pixelColor);
                    }
                }

                List <Sample> directionSamples = subPathSamples[depth];
                //Create the next Ray
                if (record.Material is LambertMaterial || record.Material is BlinnPhongMaterial)
                {
                    Sample  directionSample = Randomizer.PickRandomSample(directionSamples);
                    Vector3 direction       = UniformHemisphereSample(directionSample.X, directionSample.Y, record.SurfaceNormal);
                    record = scene.Intersect(new Ray(record.IntersectionPoint, direction));
                    if (record == null)
                    {
                        break;
                    }
                    alpha = alpha.Mult(record.Material.Diffuse.Div(1 - q));
                }
                else if (record.Material is MirrorMaterial)
                {
                    record = scene.Intersect(record.CreateReflectedRay());
                    isGeneratedFromRefraction = true;
                }
                else if (record.Material is RefractiveMaterial)
                {
                    isGeneratedFromRefraction = true;
                    float fresnel = Reflectance(record);
                    //Pick refraction / reflection path with p=0.5 each
                    if (random.NextDouble() < fresnel)
                    {
                        record = scene.Intersect(record.CreateReflectedRay());
                        alpha  = alpha.Mult(fresnel);
                    }
                    else
                    {
                        record = scene.Intersect(record.CreateRefractedRay());
                        alpha  = alpha.Mult(1 - fresnel);
                    }
                }

                depth++;
            }
            return(pixelColor);
        }
示例#18
0
 public new Vector3 GetSamplePoint(LightSample sample)
 {
     return(Intersectable.GetSamplePoint(sample));
 }
示例#19
0
        public void EvaluatePhoton(IRayEngineScene scen, float u0, float u1, float u2, float u3, float u4, out LightSample result)
        {
            result = new LightSample();
            var scene = (RayEngineScene)scen;
            float b0, b1, b2;
            Point orig;
            int index;
            var tri = SampleTriangle(u4, out index);

            tri.Sample(scene.Vertices, u0, u1, out orig, out b0, out b1, out b2);
            var TriangleNormal = triangleSampleData[index].Item2;
            var area = triangleSampleData[index].Item1;
            // Ray direction
            var sampleN = -TriangleNormal;
            Vector dir = MC.UniformSampleSphere(u2, u3);
            float rdotN = Normal.Dot(ref dir, ref sampleN);
            if (rdotN < 0f)
            {
                dir *= -1f;
                rdotN = -rdotN;
            }

            result.LightRay = new RayInfo(ref orig, ref dir);


            result.Pdf = ((MathLab.INVTWOPI / area) * (1f / mesh.TrianglesCount));

            result.Spectrum = Profile.Evaluate(b0, b1);
            result.Spectrum.Mul(rdotN);
        }
示例#20
0
        public void EvaluateShadow(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample result)
        {
            int tries = 0;

#if VERBOSE
            try
            {
#endif
                if (result == null)
                    result = new LightSample();

                var samplePoint = new Point();
                float b0, b1, b2;
                int maxTries = 1;
            startTry:

                var index = Math.Max(0, Math.Min(triangleSampleData.Length - 1, (int)(u0 * (mesh.EndTriangle - mesh.StartTriangle))));
                scene.Triangles[mesh.StartTriangle + index].Sample(scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2);
                //TriangleDataInfo.Sample(ref scene.Triangles[mesh.StartTriangle + index], scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2);
                var area = triangleSampleData[index].Item1;
                //tri.AreaV(scene.Vertices);
                //var sampleN = TriangleNormal;
                //var N = n;

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

                var nw = -wi;
                float sampleNdotMinusWi = Normal.Dot(ref triangleSampleData[index].Item2, ref nw);
                float NdotWi = Normal.Dot(ref n, ref wi);
                if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f))
                {
                    tries++;
                    if (tries > maxTries)
                    {
                        return;
                    }

                    goto startTry;
                }

                result.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 (result.Pdf <= 0.01f)
                {
                    result.Pdf = 0f;
                    result.Spectrum = GlobalConfiguration.Instance.SpectralRendering
                        ? (ISpectrum)ZeroCSpectrumArray
                        : this.RgbSpectrumZeroArray;
                    return;
                }
                result.LightRay = new RayInfo(point, wi, 1e-4f, 1e3f);
                //, MathLab.RAY_EPSILON, distance - MathLab.RAY_EPSILON);
                result.Distance = distance;
                result.Spectrum = Profile.Evaluate(b0, b1);
#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
        }
示例#21
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            HitRecord record = objects.Intersect(ray);

            Color returnColor = new Color(0, 0, 0);

            if (record != null)
            {
                foreach (ILight light in lights)
                {
                    Vector3 lightDirection = light.GetLightDirection(record.IntersectionPoint);
                    Vector3 hitPos         = record.IntersectionPoint;
                    Vector3 offset         = record.RayDirection;
                    offset  = -offset;
                    offset *= 0.001f;
                    hitPos += offset;
                    Ray       shadowRay = new Ray(hitPos, lightDirection);
                    HitRecord shadowHit = objects.Intersect(shadowRay);
                    Vector3   distance  = Vector3.Subtract(light.Position, hitPos);

                    //DEBUGGING

                    /*if (shadowHit != null && (shadowHit.Distance > distance.Length))
                     * {
                     *  returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                     * }*/
                    returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                }
            }
            return(returnColor);
        }
示例#22
0
        public void EvaluatePhoton(IRayEngineScene scene, float u0, float u1, float u2, float u3, float u4, out LightSample result)
        {
            result = new LightSample();

            var dir = MC.UniformSampleSphere(u0, u1);

            result.LightRay = new RayData(ref Position, ref dir, 1e-4f, 1e4f);

            result.Pdf = MathLab.INV4PI/Radius;
            float theta = Vector.SphericalTheta(ref result.LightRay.Dir);
            var i = (RgbSpectrumInfo)Profile.Evaluate(Vector.SphericalPhi(ref result.LightRay.Dir) * MathLab.INVTWOPI, theta * MathLab.INVPI);

            result.Spectrum = i * Radius * MathLab.M_PI * 4f;
        }
示例#23
0
        public void getSamples(ShadingState state)
        {
            if (getNumSamples() <= 0)
            {
                return;
            }
            Vector3 wc = Point3.sub(center, state.getPoint(), new Vector3());
            float   l2 = wc.LengthSquared();

            if (l2 <= r2)
            {
                return; // inside the sphere?
            }
            // top of the sphere as viewed from the current shading point
            float topX = wc.x + state.getNormal().x *radius;
            float topY = wc.y + state.getNormal().y *radius;
            float topZ = wc.z + state.getNormal().z *radius;

            if (state.getNormal().dot(topX, topY, topZ) <= 0)
            {
                return; // top of the sphere is below the horizon
            }
            float            cosThetaMax = (float)Math.Sqrt(Math.Max(0, 1 - r2 / Vector3.dot(wc, wc)));
            OrthoNormalBasis basis       = OrthoNormalBasis.makeFromW(wc);
            int   samples = state.getDiffuseDepth() > 0 ? 1 : getNumSamples();
            float scale   = (float)(2 * Math.PI * (1 - cosThetaMax));
            Color c       = Color.mul(scale / samples, radiance);

            for (int i = 0; i < samples; i++)
            {
                // random offset on unit square
                double randX = state.getRandom(i, 0, samples);
                double randY = state.getRandom(i, 1, samples);

                // cone sampling
                double  cosTheta = (1 - randX) * cosThetaMax + randX;
                double  sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);
                double  phi      = randY * 2 * Math.PI;
                Vector3 dir      = new Vector3((float)(Math.Cos(phi) * sinTheta), (float)(Math.Sin(phi) * sinTheta), (float)cosTheta);
                basis.transform(dir);

                // check that the direction of the sample is the same as the
                // normal
                float cosNx = Vector3.dot(dir, state.getNormal());
                if (cosNx <= 0)
                {
                    continue;
                }

                float    ocx = state.getPoint().x - center.x;
                float    ocy = state.getPoint().y - center.y;
                float    ocz = state.getPoint().z - center.z;
                float    qa  = Vector3.dot(dir, dir);
                float    qb  = 2 * ((dir.x * ocx) + (dir.y * ocy) + (dir.z * ocz));
                float    qc  = ((ocx * ocx) + (ocy * ocy) + (ocz * ocz)) - r2;
                double[] t   = Solvers.solveQuadric(qa, qb, qc);
                if (t == null)
                {
                    continue;
                }
                LightSample dest = new LightSample();
                // compute shadow ray to the sampled point
                dest.setShadowRay(new Ray(state.getPoint(), dir));
                // FIXME: arbitrary bias, should handle as in other places
                dest.getShadowRay().setMax((float)t[0] - 1e-3f);
                // prepare sample
                dest.setRadiance(c, c);
                dest.traceShadow(state);
                state.addSample(dest);
            }
        }
示例#24
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            scene        = objects;
            this.lights  = lights;
            this.sampler = sampler;
            HitRecord record = scene.Intersect(ray);

            if (record == null)
            {
                if (SkyBox.IsSkyBoxLoaded())
                {
                    return(SkyBox.GetSkyBoxColor(ray));
                }
                return(new Color(0, 0, 0));
            }

            if (record.HitObject.Light != null)
            {
                return(record.HitObject.Light.LightColor);
            }
            return(PathTrace(ray, record, subPathSamples, lightSample));
        }
示例#25
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            HitRecord record = objects.Intersect(ray);

            if (record != null)
            {
                return(new Color(1, 1, 1));
            }
            else
            {
                return(new Color(0, 0, 0));
            }
        }
示例#26
0
            public void getSamples(ShadingState state)
            {
                if (meshlight.numSamples == 0)
                {
                    return;
                }
                Vector3 n = state.getNormal();
                Point3  p = state.getPoint();
                // vector towards each vertex of the light source
                Vector3 p0 = Point3.sub(meshlight.getPoint(meshlight.triangles[tri3 + 0]), p, new Vector3());

                // cull triangle if it is facing the wrong way
                if (Vector3.dot(p0, ng) >= 0)
                {
                    return;
                }
                Vector3 p1 = Point3.sub(meshlight.getPoint(meshlight.triangles[tri3 + 1]), p, new Vector3());
                Vector3 p2 = Point3.sub(meshlight.getPoint(meshlight.triangles[tri3 + 2]), p, new Vector3());

                // if all three vertices are below the hemisphere, stop
                if (Vector3.dot(p0, n) <= 0 && Vector3.dot(p1, n) <= 0 && Vector3.dot(p2, n) <= 0)
                {
                    return;
                }
                p0.normalize();
                p1.normalize();
                p2.normalize();
                float   dot = Vector3.dot(p2, p0);
                Vector3 h   = new Vector3();

                h.x = p2.x - dot * p0.x;
                h.y = p2.y - dot * p0.y;
                h.z = p2.z - dot * p0.z;
                float hlen = h.Length();

                if (hlen > 1e-6f)
                {
                    h.div(hlen);
                }
                else
                {
                    return;
                }
                Vector3 n0   = Vector3.cross(p0, p1, new Vector3());
                float   len0 = n0.Length();

                if (len0 > 1e-6f)
                {
                    n0.div(len0);
                }
                else
                {
                    return;
                }
                Vector3 n1   = Vector3.cross(p1, p2, new Vector3());
                float   len1 = n1.Length();

                if (len1 > 1e-6f)
                {
                    n1.div(len1);
                }
                else
                {
                    return;
                }
                Vector3 n2   = Vector3.cross(p2, p0, new Vector3());
                float   len2 = n2.Length();

                if (len2 > 1e-6f)
                {
                    n2.div(len2);
                }
                else
                {
                    return;
                }

                float cosAlpha = MathUtils.clamp(-Vector3.dot(n2, n0), -1.0f, 1.0f);
                float cosBeta  = MathUtils.clamp(-Vector3.dot(n0, n1), -1.0f, 1.0f);
                float cosGamma = MathUtils.clamp(-Vector3.dot(n1, n2), -1.0f, 1.0f);

                float alpha = (float)Math.Acos(cosAlpha);
                float beta  = (float)Math.Acos(cosBeta);
                float gamma = (float)Math.Acos(cosGamma);

                float area = alpha + beta + gamma - (float)Math.PI;

                float cosC    = MathUtils.clamp(Vector3.dot(p0, p1), -1.0f, 1.0f);
                float salpha  = (float)Math.Sin(alpha);
                float product = salpha * cosC;

                // use lower sampling depth for diffuse bounces
                int   samples = state.getDiffuseDepth() > 0 ? 1 : meshlight.numSamples;
                Color c       = Color.mul(area / samples, meshlight.radiance);

                for (int i = 0; i < samples; i++)
                {
                    // random offset on unit square
                    double randX = state.getRandom(i, 0, samples);
                    double randY = state.getRandom(i, 1, samples);

                    float phi    = (float)randX * area - alpha + (float)Math.PI;
                    float sinPhi = (float)Math.Sin(phi);
                    float cosPhi = (float)Math.Cos(phi);

                    float u = cosPhi + cosAlpha;
                    float v = sinPhi - product;

                    float q  = (-v + cosAlpha * (cosPhi * -v + sinPhi * u)) / (salpha * (sinPhi * -v - cosPhi * u));
                    float q1 = 1.0f - q * q;
                    if (q1 < 0.0f)
                    {
                        q1 = 0.0f;
                    }

                    float sqrtq1 = (float)Math.Sqrt(q1);
                    float ncx    = q * p0.x + sqrtq1 * h.x;
                    float ncy    = q * p0.y + sqrtq1 * h.y;
                    float ncz    = q * p0.z + sqrtq1 * h.z;
                    dot = p1.dot(ncx, ncy, ncz);
                    float z  = 1.0f - (float)randY * (1.0f - dot);
                    float z1 = 1.0f - z * z;
                    if (z1 < 0.0f)
                    {
                        z1 = 0.0f;
                    }
                    Vector3 nd = new Vector3();
                    nd.x = ncx - dot * p1.x;
                    nd.y = ncy - dot * p1.y;
                    nd.z = ncz - dot * p1.z;
                    nd.normalize();
                    float   sqrtz1 = (float)Math.Sqrt(z1);
                    Vector3 result = new Vector3();
                    result.x = z * p1.x + sqrtz1 * nd.x;
                    result.y = z * p1.y + sqrtz1 * nd.y;
                    result.z = z * p1.z + sqrtz1 * nd.z;

                    // make sure the sample is in the right hemisphere - facing in
                    // the right direction
                    if (Vector3.dot(result, n) > 0 && Vector3.dot(result, state.getGeoNormal()) > 0 && Vector3.dot(result, ng) < 0)
                    {
                        // compute intersection with triangle (if any)
                        Ray shadowRay = new Ray(state.getPoint(), result);
                        if (!intersectTriangleKensler(shadowRay))
                        {
                            continue;
                        }
                        LightSample dest = new LightSample();
                        dest.setShadowRay(shadowRay);
                        // prepare sample
                        dest.setRadiance(c, c);
                        dest.traceShadow(state);
                        state.addSample(dest);
                    }
                }
            }
示例#27
0
 public abstract Color Sample(Ray3 ray, LightSample lightSample, Vector3 normal, Vector3 position, Vector2 textureCoordinates = null);
示例#28
0
        public virtual void EvaluatePhoton(IRayEngineScene scen, float u0, float u1, float u2, float u3, float u4, out LightSample result)
        {
            result = new LightSample();
            var scene = (RayEngineScene) scen;

            var worldCenter = scene.SceneGeometry.BoundingSphereCenter;
            var worldRadius = scene.SceneGeometry.BoundingSphereRadius * 1.01f;

            var p1 = worldCenter + worldRadius * MC.UniformSampleSphere(u0, u1);
            var p2 = worldCenter + worldRadius * MC.UniformSampleSphere(u2, u3);

            // Construct ray between p1 and p2
            result.LightRay = new RayData(p1, (p2 - p1).Normalize(), 1e-4f, 1e4f);

            // Compute InfiniteAreaLight ray weight
            Vector toCenter = (worldCenter - p1).Normalize();
            var rayDir = result.LightRay.Dir;
            float costheta = MathLab.AbsDot(ref toCenter, ref rayDir);
            result.Pdf = costheta / (4f * MathLab.M_PI * MathLab.M_PI * worldRadius * worldRadius);

            result.Spectrum = Le(ref result.LightRay.Dir);
        }
示例#29
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            int currentTriangleIndex = 0;
            SurfaceIntersectionData hitInfo = null;
#if VERBOSE

            try
            {
#endif

                base.Advance(rayBuffer, consumer);

                RayHit rayHit = rayBuffer.rayHits[RayIndex];

                if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                    (tracedShadowRayCount > 0))
                {
                    for (int i = 0; i < tracedShadowRayCount; ++i)
                    {
                        RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex];
                        RgbSpectrum attenuation;
                        if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                        {
                            //                            Radiance.MADD()
                            mutate = true;
                            Radiance += attenuation * ((secRays[i].color));
                            pathWeight *= secRays[i].pdf;
                        }
                    }
                    Splat(consumer);

                    return;
                }

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                {
                    if (specularBounce && missed)
                    {
                        Radiance += this.SampleEnvironment(PathRay.Dir) * Throughput;
                    }
                    Splat(consumer);

                    return;
                }

                // Something was hit
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                currentTriangleIndex = (int)rayHit.Index;

                if (hitInfo == null)
                {
                    Debugger.Break();
                }
                //If Hit light)
                if (hitInfo.IsLight)
                {
                    if (specularBounce)
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt != null)
                        {
                            var le = (RgbSpectrum)(lt.Le(ref PathRay.Dir));
                            Radiance += Throughput * le;
                            mutate = true;
                        }
                    }
                    Splat(consumer);

                    return;
                }

                var hitPoint = PathRay.Point(rayHit.Distance);

                Vector wo = -PathRay.Dir;
                tracedShadowRayCount = 0;
                if (hitInfo.MMaterial.IsDiffuse())
                {
                    float lightStrategyPdf = 1f;// scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRayCount; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue(depth * 0));
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint, ref hitInfo.ShadingNormal, Sample.GetLazyValue(depth * 1), Sample.GetLazyValue(depth * 2), Sample.GetLazyValue(depth * 3), ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        secRays[tracedShadowRayCount].color = (RgbSpectrum)(ls.Spectrum);
                        secRays[tracedShadowRayCount].pdf = ls.Pdf;
                        secRays[tracedShadowRayCount].shadowRay = ls.LightRay;

                        Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir;
                        RgbSpectrum fs;
                        hitInfo.MMaterial.f(
                            ref secRays[tracedShadowRayCount].shadowRay.Dir,
                            ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse);
                        secRays[tracedShadowRayCount].color *= lightTroughtput *
                                                               Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                               fs;
                        if (!secRays[tracedShadowRayCount].color.IsBlack())
                        {
                            secRays[tracedShadowRayCount].pdf *= lightStrategyPdf;
                            tracedShadowRayCount++;
                        }
                    }
                }

                float fPdf;
                Vector wi;

                RgbSpectrum f = hitInfo.MMaterial.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                                          Sample.GetLazyValue(depth * 4), Sample.GetLazyValue(depth * 5),
                                                          Sample.GetLazyValue(depth * 6), ref hitInfo.TextureData, 
                                                          out fPdf, out specularBounce);

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);

                    }
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= f / fPdf;
                if (!mutate)
                    mutate = Throughput.Filter() > Sample.GetLazyValue(depth*7);

                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue(depth * 8))
                    {
                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    else
                    {
                        if (tracedShadowRayCount > 0)
                            PathState = PathTracerPathState.ShadowRaysOnly;
                        else
                        {
                            Splat(consumer);
                        }

                        return;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = PathTracerPathState.NextVertex;

#if VERBOSE
            }
            catch (Exception ex)
            {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
示例#30
0
        public void getSamples(ShadingState state)
        {
            if (samples == null)
            {
                int n = state.getDiffuseDepth() > 0 ? 1 : numSamples;
                for (int i = 0; i < n; i++)
                {
                    // random offset on unit square, we use the infinite version of
                    // getRandom because the light sampling is adaptive
                    double randX = state.getRandom(i, 0, n);
                    double randY = state.getRandom(i, 1, n);
                    int    x     = 0;
                    while (randX >= colHistogram[x] && x < colHistogram.Length - 1)
                    {
                        x++;
                    }
                    float[] rowHistogram = imageHistogram[x];
                    int     y            = 0;
                    while (randY >= rowHistogram[y] && y < rowHistogram.Length - 1)
                    {
                        y++;
                    }
                    // sample from (x, y)
                    float u = (float)((x == 0) ? (randX / colHistogram[0]) : ((randX - colHistogram[x - 1]) / (colHistogram[x] - colHistogram[x - 1])));
                    float v = (float)((y == 0) ? (randY / rowHistogram[0]) : ((randY - rowHistogram[y - 1]) / (rowHistogram[y] - rowHistogram[y - 1])));

                    float px = ((x == 0) ? colHistogram[0] : (colHistogram[x] - colHistogram[x - 1]));
                    float py = ((y == 0) ? rowHistogram[0] : (rowHistogram[y] - rowHistogram[y - 1]));

                    float   su   = (x + u) / colHistogram.Length;
                    float   sv   = (y + v) / rowHistogram.Length;
                    float   invP = (float)Math.Sin(sv * Math.PI) * jacobian / (n * px * py);
                    Vector3 dir  = getDirection(su, sv);
                    basis.transform(dir);
                    if (Vector3.dot(dir, state.getGeoNormal()) > 0)
                    {
                        LightSample dest = new LightSample();
                        dest.setShadowRay(new Ray(state.getPoint(), dir));
                        dest.getShadowRay().setMax(float.MaxValue);
                        Color radiance = texture.getPixel(su, sv);
                        dest.setRadiance(radiance, radiance);
                        dest.getDiffuseRadiance().mul(invP);
                        dest.getSpecularRadiance().mul(invP);
                        dest.traceShadow(state);
                        state.addSample(dest);
                    }
                }
            }
            else
            {
                if (state.getDiffuseDepth() > 0)
                {
                    for (int i = 0; i < numLowSamples; i++)
                    {
                        if (Vector3.dot(lowSamples[i], state.getGeoNormal()) > 0 && Vector3.dot(lowSamples[i], state.getNormal()) > 0)
                        {
                            LightSample dest = new LightSample();
                            dest.setShadowRay(new Ray(state.getPoint(), lowSamples[i]));
                            dest.getShadowRay().setMax(float.MaxValue);
                            dest.setRadiance(lowColors[i], lowColors[i]);
                            dest.traceShadow(state);
                            state.addSample(dest);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < numSamples; i++)
                    {
                        if (Vector3.dot(samples[i], state.getGeoNormal()) > 0 && Vector3.dot(samples[i], state.getNormal()) > 0)
                        {
                            LightSample dest = new LightSample();
                            dest.setShadowRay(new Ray(state.getPoint(), samples[i]));
                            dest.getShadowRay().setMax(float.MaxValue);
                            dest.setRadiance(colors[i], colors[i]);
                            dest.traceShadow(state);
                            state.addSample(dest);
                        }
                    }
                }
            }
        }
示例#31
0
        public override sealed void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
             int currentTriangleIndex = 0;
#if VERBOSE

            try {
#endif

            if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                (tracedShadowRayCount > 0))
            {
                for (int i = 0; i < tracedShadowRayCount; ++i)
                {
                    RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex];
                    RgbSpectrum attenuation;
                    bool continueTrace;
                    if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace))
                    {

                        Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf);
                        pathWeight *= secRays[i].Pdf;
                    }

                    if (continueTrace)
                    {
                        continueRays[contCount++] = secRays[i];
                        //continueRays.Add(secRays[i]);
                    }
                }

                if (PathState == PathTracerPathState.ShadowRaysOnly)
                {
                    Splat(consumer);
                    return;
                }

                Array.Copy(continueRays, secRays, contCount);
                tracedShadowRayCount = contCount;
                contCount = 0;
            }
            RayHit rayHit = rayBuffer.rayHits[RayIndex];
            Vector wo = -PathRay.Dir;

            depth++;
            bool missed = rayHit.Index == 0xffffffffu;
            if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
            {
                if (missed)
                {
                    //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput;
                    var sampledEnvironment = this.scene.SampleEnvironment(ref wo);
                    Radiance.MAdd(ref sampledEnvironment , ref Throughput);
                }
                Splat(consumer);

                return;
            }

            //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex);
            //rayHit.Index += (uint)mesh.StartTriangle;
            // Something was hit
            if (hitInfo == null)
            {
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
            }
            else
            {
                SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
            }
            currentTriangleIndex = (int)rayHit.Index;

            if (hitInfo == null)
            {
                Debugger.Break();
            }
            //If Hit light)

            if (hitInfo.IsLight)
            {
                if (specularBounce || depth == 1)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);
                    if (lt != null)
                    {
                        float pdf;
                        var le = hitInfo.Color * lt.Emittance(ref wo, out pdf);
                        //Radiance += Throughput * le;
                        
                        Radiance.MAdd(ref Throughput, ref le);
                    }
                }
                Splat(consumer);

                return;
            }

            var hitPoint = PathRay.Point(rayHit.Distance);

            tracedShadowRayCount = 0;
            var bsdf = hitInfo.MMaterial;

            if (!hitInfo.TextureData.Alpha.IsBlack())
            {
                Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum) hitInfo.TextureData.Alpha);
                PathRay = new RayData(hitPoint, -wo);
                return;
            }

            if (bsdf.IsDiffuse())
            {
                float lightStrategyPdf = LightSampler.StrategyPdf;
                //scene.ShadowRaysPerSample/(float)scene.Lights.Length;
                RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(),
                                            Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                for (int index = 0; index < ls.Length; index++)
                {

                    if (ls[index].Pdf <= 0f)
                        continue;
                    secRays[tracedShadowRayCount].Throughput = ls[index].Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum) (RgbSpectrumInfo)ls[index].Spectrum : (RgbSpectrum)ls[index].Spectrum;
                    secRays[tracedShadowRayCount].Pdf = ls[index].Pdf;
                    secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay;
                    Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir;
                    RgbSpectrum fs;
                    hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse);
                    secRays[tracedShadowRayCount].Throughput *= lightTroughtput *
                                                                Vector.AbsDot(ref hitInfo.Normal, ref lwi) *
                                                                fs;
                    if (!secRays[tracedShadowRayCount].Throughput.IsBlack())
                    {
#if DEBUG
                        RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf);
#endif
                        secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf;
                        LightSample = ls[index];
                        tracedShadowRayCount++;
                    }
                }
            }

            float fPdf = 0f;
            var wi = new Vector();
            RgbSpectrum f;
            hitInfo.TextureData.Throughput = Throughput;
            f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue()
                                , ref hitInfo.TextureData, out fPdf, out specularBounce);

            if ((fPdf <= 0.0f) || f.IsBlack())
            {
                if (tracedShadowRayCount > 0)
                    PathState = PathTracerPathState.ShadowRaysOnly;
                else
                {
                    Splat(consumer);

                }
                return;
            }
            CurrentVertices.Add(new PathVertex()
            {
                BsdfPdf = fPdf,
                Throughput = Throughput,
                GeoNormal = hitInfo.Normal,
                HitPoint = hitPoint,
                HitType = PathVertexType.Geometry,
                IncomingDirection = wi,
                Material = bsdf,
                OutgoingDirection = wo,
                RayDistance = rayHit.Distance,
                SampleU = rayHit.U,
                SampleV = rayHit.V,
                ShadingNormal = hitInfo.ShadingNormal,
                TexCoords = hitInfo.TexCoords,
                rrWeight = 1f,
            });
            pathWeight *= fPdf;
            Throughput *= (f * hitInfo.Color) / fPdf;

            if (depth > scene.MaxPathDepth)
            {
                float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                if (prob >= Sample.GetLazyValue())
                {
                    CurrentVertices[CurrentVertices.Count - 1].rrWeight = 1f/prob;
                    Throughput /= prob;
                    pathWeight *= prob;
                }
                else
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);

                    }

                    return;
                }
            }

            PathRay.Org = hitPoint;
            PathRay.Dir = wi.Normalize();
            PathState = PathTracerPathState.NextVertex;


#if VERBOSE
            }
            catch (Exception ex) {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
示例#32
0
        public void EvaluateShadow(ref Point point, ref Normal normal, float u0, float u1, float u2, ref LightSample result)
        {
            if (result == null)
                result = new LightSample();

            var samplePoint = new Point();
            float b0, b1, b2;

            scene.Triangles[triangleIndex].Sample(scene.Vertices, u0, u1, out samplePoint, out b0, out b1, out b2);

            var sampleN =
                //-scene.Triangles[triangleIndex].ComputeNormal(scene.Vertices);
                //scene.Triangles[triangleIndex].InterpolateNormal(scene.Vertices, b0, b1);
            TriangleNormal.Normalize();
            var N = normal.Normalize();

            Vector wi = samplePoint - point;
            float distanceSquared = wi.Length2();
            float distance = MathLab.Sqrt(distanceSquared);
            wi /= distance;

            var nw = -wi;
            float sampleNdotMinusWi = Normal.Dot(ref sampleN, ref nw);
            float NdotWi = Normal.Dot(ref N, ref wi);
            if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f))
            {
                result.Pdf = 0f;
                result.LightRay = new RayData();
                result.Spectrum = GlobalConfiguration.Instance.SpectralRendering ? ZeroCSpectrumArray : RgbSpectrumZeroArray;
                return;
            }


            result.LightRay = new RayData(ref point, ref wi,
#if SHORT_RAYS

 MathLab.RAY_EPSILON, distance - MathLab.RAY_EPSILON);
#else
                                         MathLab.RAY_EPSILON, distanceSquared);

#endif

            result.Pdf = (distanceSquared / (sampleNdotMinusWi * area));

            // Using 0.1 instead of 0.0 to cut down fireflies
            if (result.Pdf <= 0.1f)
            {
                result.Pdf = 0f;
                result.Spectrum = GlobalConfiguration.Instance.SpectralRendering ? ZeroCSpectrumArray : RgbSpectrumZeroArray;

                return;
            }
#if DEBUG
            Assert.IsNotNaN(result.Pdf);
#endif
            result.Distance = distance;
            result.Spectrum = Profile.Evaluate(b0, b1);
        }
示例#33
0
 public Vector3 GetSamplePoint(LightSample sample)
 {
     throw new NotImplementedException();
 }
示例#34
0
 public Vector3 GetSamplePoint(LightSample sample)
 {
     throw new NotSupportedException();
 }
示例#35
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            base.Advance(rayBuffer, consumer);

            if ((PathState == BDPTSamplerState.ConnectOnly || PathState == BDPTSamplerState.PropagatePath) &&
                tracedConnectRayCount > 0)
            {
                for (int i = 0; i < tracedConnectRayCount; ++i)
                {
                    RayHit shadowRayHit = rayBuffer.rayHits[connectRays[i].ConnectRayIndex];
                    RgbSpectrum attenuation;
                    if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                    {
                        //                            Radiance.MADD()
                        Radiance += attenuation * ((connectRays[i].Radiance) / connectRays[i].Pdf);
                        //pathWeight *= connectRays[i].pdf;
                    }
                }
                Splat(consumer);
                return;
            }

            if (!lightStop)
            {
                RayHit rayHit = rayBuffer.rayHits[LightRayIndex];
                lightDepth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || lightDepth > MaxLightDepth)
                {
                    lightStop = true;
                    goto Eye;
                }
                // Something was hit
                if (hitInfo == null)
                {
                    hitInfo = SurfaceSampler.GetIntersection(ref LightRay, ref rayHit);
                }
                else
                {
                    SurfaceSampler.GetIntersection(ref LightRay, ref rayHit, ref hitInfo);
                }
                var hitPoint = LightRay.Point(rayHit.Distance);

                if (scene.IsLight((int)rayHit.Index))
                {
                    lightStop = true;
                    goto Eye;
                }

                Vector wo = -LightRay.Dir;
                var bsdf = hitInfo.MMaterial;
                float fPdf;
                Vector wi;
                bool specularBounce;
                hitInfo.Color = RgbSpectrum.UnitSpectrum();

                RgbSpectrum f = bsdf.Sample_f(ref wo,
                                                out wi,
                                                ref hitInfo.Normal,
                                                ref hitInfo.ShadingNormal, ref LightThroughput,
                                                Sample.GetLazyValue(),
                                                Sample.GetLazyValue(),
                                                Sample.GetLazyValue(),
                                                ref hitInfo.TextureData,
                                                out fPdf,
                                                out specularBounce);

                if (f.IsBlack() && fPdf <= 0f)
                {
                    this.lightStop = true;
                    goto Eye;
                }

                if (bsdf.IsDiffuse() && !f.IsBlack() && lightVertices < MaxLightDepth)
                {
                    this.lightPath[lightVertices].HitPoint = hitPoint;
                    this.lightPath[lightVertices].Wi = wo;
                    this.lightPath[lightVertices].GeoNormal = hitInfo.Normal;
                    this.lightPath[lightVertices].Throughput = LightThroughput;
                    this.lightPath[lightVertices].Pdf = this.lightPdf;
                    lightVertices++;
                }

                //this.lightPdf /= fPdf;
                this.LightThroughput *= f / fPdf;

                if (lightDepth > MaxLightDepth)
                {
                    this.lightStop = true;
                    goto Eye;
                }

                LightRay.Org = hitPoint;
                LightRay.Dir = wi.Normalize();
                PathState = BDPTSamplerState.PropagatePath;
            }

            // Eye path sampling
        Eye:
            if (!eyeStop)
            {
                RayHit rayHit = rayBuffer.rayHits[RayIndex];
                eyeDepth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || eyeDepth > scene.MaxPathDepth)
                {
                    Radiance += this.SampleEnvironment(PathRay.Dir) * EyeThroughput;
                    Splat(consumer);
                    return;
                }

                // Something was hit
                if (hitInfo == null)
                {
                    hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                }
                else
                {
                    SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
                }
                var currentTriangleIndex = (int)rayHit.Index;
                if (hitInfo.IsLight)
                {
                    //if (specularBounce) 
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt != null)
                        {
                            var le = (RgbSpectrum)(lt.Le(ref PathRay.Dir));
                            Radiance += EyeThroughput * le;
                        }
                    }
                    Splat(consumer);

                    return;
                }
                var hitPoint = PathRay.Point(rayHit.Distance);

                Vector wo = -PathRay.Dir;
                var bsdf = hitInfo.MMaterial;
                float fPdf;
                Vector wi;
                bool specularBounce;
                if (bsdf.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = EyeThroughput * hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRayCount; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint,
                                             ref hitInfo.ShadingNormal,
                                             Sample.GetLazyValue(),
                                             Sample.GetLazyValue(),
                                             Sample.GetLazyValue(),
                                             ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        connectRays[tracedConnectRayCount].Radiance = (RgbSpectrum)(ls.Spectrum);
                        connectRays[tracedConnectRayCount].Pdf = ls.Pdf;
                        connectRays[tracedConnectRayCount].ConnectRay = ls.LightRay;
                        connectRays[tracedConnectRayCount].Direct = true;

                        Vector mwi = connectRays[tracedConnectRayCount].ConnectRay.Dir;
                        Vector lwi = connectRays[tracedConnectRayCount].ConnectRay.Dir;
                        RgbSpectrum fs;

                        hitInfo.MMaterial.f(
                            ref mwi,
                            ref wo,
                            ref hitInfo.ShadingNormal, ref lightTroughtput, 
                            out fs,
                            types: BrdfType.Diffuse);
                        connectRays[tracedConnectRayCount].Radiance *= lightTroughtput *
                                                                       Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                                       fs;
                        if (!connectRays[tracedConnectRayCount].Radiance.IsBlack())
                        {
                            connectRays[tracedConnectRayCount].Pdf *= lightStrategyPdf;
                            tracedConnectRayCount++;
                        }
                    }

                    for (int i = 0; i < lightVertices; i++)
                    {

                        var lightThroughtput = lightPath[i].Throughput;

                        connectRays[tracedConnectRayCount].Radiance = EyeThroughput * hitInfo.Color;
                        connectRays[tracedConnectRayCount].Pdf = 1f;
                        connectRays[tracedConnectRayCount].ConnectRay = new RayData(hitPoint, (hitPoint - lightPath[i].HitPoint).Normalize());
                        var lwi = -connectRays[tracedConnectRayCount].ConnectRay.Dir;


                        connectRays[tracedConnectRayCount].Radiance *= lightThroughtput *
                                                                       Geometry.G(ref hitPoint, ref lightPath[i].HitPoint, ref hitInfo.Normal, ref lightPath[i].GeoNormal);
                        //     Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi);
                        if (!connectRays[tracedConnectRayCount].Radiance.IsBlack())
                        {
                            connectRays[tracedConnectRayCount].Pdf *= lightPath[i].Pdf*eyePdf;
                            tracedConnectRayCount++;
                        }
                    }

                }

                RgbSpectrum f = bsdf.Sample_f(ref wo,
                                                  out wi,
                                                  ref hitInfo.Normal,
                                                  ref hitInfo.ShadingNormal, ref EyeThroughput,
                                                  Sample.GetLazyValue(),
                                                  Sample.GetLazyValue(),
                                                  Sample.GetLazyValue(),
                                                  ref hitInfo.TextureData,
                                                  out fPdf,
                                                  out specularBounce);
                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedConnectRayCount > 0)
                        PathState = BDPTSamplerState.ConnectOnly;
                    else
                    {
                        //Splat(consumer);
                        eyeStop = true;
                    }
                    eyeStop = true;
                    goto Connect;
                }

                eyePdf *= fPdf;
                EyeThroughput *= (f) / fPdf;
                if (eyeDepth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(EyeThroughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {
                        EyeThroughput /= prob;
                        eyePdf *= prob;
                    }
                    else
                    {
                        if (tracedConnectRayCount > 0)
                            PathState = BDPTSamplerState.ConnectOnly;
                        else
                        {
                            eyeStop = true;
                            goto Connect;
                        }

                        eyeStop = true;
                        goto Connect;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = BDPTSamplerState.PropagatePath;
            }

        @Connect:
            if (eyeStop && lightStop)
            {
                this.Splat(consumer);
                return;
            }
        }
示例#36
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            shadowIntegrator = new ShadowIntegrator();
            Color     returnColor = new Color(0, 0, 0);
            HitRecord record      = objects.Intersect(ray);

            if (record != null)
            {
                if (!(record.Material is MirrorMaterial))
                {
                    returnColor.Append(shadowIntegrator.Integrate(ray, objects, lights, sampler, subPathSamples, lightSample));
                }
                if (record.Material is MirrorMaterial && record.Material.Specular.R > 0 && record.Material.Specular.G > 0 && record.Material.Specular.B > 0)
                {
                    returnColor.Append(Reflection(ray, record, 0, returnColor, objects, lights, sampler, subPathSamples, lightSample));
                }
            }
            else
            {
                if (SkyBox.IsSkyBoxLoaded())
                {
                    returnColor = SkyBox.GetSkyBoxColor(ray);
                }
            }
            return(returnColor);
        }
示例#37
0
        public new Vector3 GetSamplePoint(LightSample sample)
        {
            Triangle sampleTriangle = Triangles[(int)Math.Floor(new Random().NextDouble() * Triangles.Count)];

            return(sampleTriangle.GetSamplePoint(sample));
        }
        public override void GenerateLiRays(IRayEngineScene scn, Sample sample, ref RayData ray, VolumeComputation comp)
        {
            comp.Reset();
            var scene = (RayEngineScene)(scn);

            var sigs = sig_s;
            comp.EmittedLight = lightEmission;
            float t0, t1;
            if (!region.Intersect(ray, out t0, out t1))
                return;

            if (sigs.IsBlack() || (scene.Lights.Length < 1))
            {
                float distance = t1 - t0;
                comp.EmittedLight = lightEmission * distance;
            }
            else
            {
                // Prepare for volume integration stepping
                float distance = t1 - t0;
                var nSamples = MathLab.Ceil2UInt(distance / stepSize);

                float step = distance / nSamples;
                RgbSpectrum Tr = new RgbSpectrum(1f);
                RgbSpectrum Lv = new RgbSpectrum();
                var p = ray.Point(t0);
                float offset = sample.GetLazyValue();
                t0 += offset * step;

                //Vector pPrev;
                for (var i = 0; i < nSamples; ++i, t0 += step)
                {
                    //pPrev = p;
                    p = ray.Point(t0);
                    Sigma_s(ref p, out sigs);
                    //sigs = NoiseProvider.Instance.Noise3D(((Vector)p).Normalize());
                    Lv += lightEmission;
                    if (!sigs.IsBlack() && (scene.Lights.Length) > 0)
                    {
                        // Select the light to sample
                        float lightStrategyPdf;
                        var light = scene.Lights[scene.SampleLights(sample.GetLazyValue(), out lightStrategyPdf)];

                        // Select a point on the light surface
                        float lightPdf;
                        Normal fakeNorml = new Normal(0f, 0f, 1f);
                        LightSample ls = new LightSample();
                        light.EvaluateShadow(ref p, ref fakeNorml, sample.GetLazyValue(),
                                                                sample.GetLazyValue(), sample.GetLazyValue(), ref ls);


                        var lightColor = (RgbSpectrumInfo)(ls.Spectrum);
                        lightPdf = ls.Pdf;
                        comp.Rays[comp.RayCount] = ls.LightRay;

                        if ((lightPdf > 0f) && !lightColor.IsBlack())
                        {
                            comp.ScatteredLight[comp.RayCount] =(RgbSpectrum)(Tr * sigs * lightColor * MathLab.Exp(-distance) *
                                                                 ((Density(ref p) * step) / (4f * MathLab.M_PI * lightPdf * lightStrategyPdf)));
                            comp.RayCount++;
                        }
                    }

                    comp.EmittedLight = Lv * step;
                }
            }
        }
示例#39
0
            public ExplicitLightVertex CreateLightVertex(Sample sample, GeometryVertex vertex)
            {

                int currentLightIndex = scene.SampleLights(sample.GetLazyValue());
                var light = scene.Lights[currentLightIndex];

                var ls = new LightSample();
                light.EvaluateShadow(ref vertex.Point, ref vertex.GeometryNormal, sample.GetLazyValue(), sample.GetLazyValue(), sample.GetLazyValue(), ref ls);
                if (ls.Pdf <= 0f)
                {
                    throw new Exception();
                }
                /*
                secRays[tracedShadowRayCount].color = new RgbSpectrum(ls.Spectrum);
                secRays[tracedShadowRayCount].pdf = ls.Pdf;
                secRays[tracedShadowRayCount].shadowRay = ls.LightRay;

                Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir;
                RgbSpectrum fs;
                hitInfo.MMaterial.f(
                    ref secRays[tracedShadowRayCount].shadowRay.Dir,
                    ref wo, ref hitInfo.ShadingNormal, out fs, BrdfType.Diffuse);
                secRays[tracedShadowRayCount].color *= lightTroughtput *
                                                       Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                       fs;
                */
                return new ExplicitLightVertex()
                    {
                        
                    };
            }
示例#40
0
        public void SampleSpatialDirect(ref Point point, ref Normal n, float u0, float u1, float u2, ref LightSample ls)
        {
            int tries = 0;

#if VERBOSE
            try
            {
#endif
            var samplePoint = new Point();
            float b0, b1, b2;
            int maxTries = 1;
        startTry:

            TriangleDataInfo.Sample(ref scene.Triangles[triangleIndex], scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2);
            var triangleNormal = TriangleNormal;
            //tri.AreaV(scene.Vertices);
            //var sampleN = TriangleNormal;
            //var N = n;

            ls.U = b0;
            ls.V = b1;
            Vector wi = samplePoint - point;
            //wi.Normalize();
            float distanceSquared = wi.Length2();
            ls.Distance = MathLab.Sqrt(distanceSquared);
            wi /= ls.Distance;

            var nw = -wi;
            float sampleNdotMinusWi = Normal.Dot(ref triangleNormal, ref nw);
            float NdotWi = Normal.Dot(ref n, ref wi);
            if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f))
            {
                tries++;
                if (tries > maxTries)
                {
                    ls.Pdf = 0f;
                    return;
                }

                goto startTry;
            }

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




            // Using 0.01 instead of 0.0 to cut down fireflies
            if (ls.Pdf <= 0.01f)
            {
                ls.Pdf = 0f;
                return;
            }
            ls.LightRay.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
        }
示例#41
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer, Action<PathSamplerBase> onRestart)
        {
            int currentTriangleIndex = 0;
            SurfaceIntersectionData hitInfo = null;

#if VERBOSE

            try
            {
#endif

                base.Advance(rayBuffer, consumer, onRestart);



                if (((this.PathState == GenericPathSamplerState.Connection)))
                {
                    for (int i = 0; i < tracedShadowRayCount; i++)
                    {
                        connections[i].Connected = rayBuffer.rayHits[connections[i].CurrentShadowRayIndex].Miss();
                    }

                    PathState = GenericPathSamplerState.Evaluation;
                    return;
                }
                var rayHit = rayBuffer.rayHits[RayIndex];

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;


                if (missed)
                {
                    if (depth <= scene.MaxPathDepth)
                    {
                        vertices[currentVertice] = new EnvironmentPathElement()
                            {
                                Throughput = SampleEnvironment(-PathRay.Dir)
                            };
                    }
                    if (PathState == GenericPathSamplerState.Initialized || PathState == GenericPathSamplerState.Sampling)
                    {
                        PathState = GenericPathSamplerState.Connection;
                        return;
                    }
                }

                // Something was hit
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);

                currentTriangleIndex = (int)rayHit.Index;


                if (hitInfo == null)
                {
                    Debugger.Break();
                    return;
                }
                var hitPoint = PathRay.Point(rayHit.Distance);

                //If Hit light)
                if (hitInfo.IsLight)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);
                    vertices[currentVertice] = new LightsourcePathElement()
                        {
                            HitInfo = hitInfo,
                            Throughput = this.Throughput,
                            LightSample = new LightSample()
                                {
                                    Spectrum = lt.Le(ref PathRay.Dir),
                                    Pdf = 1f

                                }
                        };
                    PathState = GenericPathSamplerState.Evaluation;
                    return;
                }


                Vector wo = -PathRay.Dir;



                float fPdf;
                Vector wi;
                float u0 = Sample.GetLazyValue(), u1 = Sample.GetLazyValue(), u2 = Sample.GetLazyValue();
                RgbSpectrum f = hitInfo.Material.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal,
                                                          u0, u1, u2,
                                                          out fPdf, out specularBounce) * hitInfo.Color;

                vertices[currentVertice] = new GeometryPathElement()
                    {
                        HitInfo = hitInfo,
                        HitPoint = hitPoint,
                        BsdfSample = new BsdfSample()
                            {
                                SampleData = new[] { u0, u1, u2 },
                                Wi = wi,
                                Pdf = fPdf,
                                Spectrum = f.ToArray(),
                                SpecularBounce = specularBounce
                            }
                    };
                if (hitInfo.Material.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRayCount; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint, ref hitInfo.ShadingNormal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), out ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        connections[tracedShadowRayCount].Throughput = new RgbSpectrum(ls.Spectrum);
                        connections[tracedShadowRayCount].Pdf = ls.Pdf;
                        connections[tracedShadowRayCount].Ray = ls.LightRay;

                        Vector lwi = connections[tracedShadowRayCount].Ray.Dir;
                        connections[tracedShadowRayCount].Throughput *= lightTroughtput *
                                                               Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                               hitInfo.Material.f(
                                                                   ref connections[tracedShadowRayCount].Ray.Dir,
                                                                   ref wo, ref hitInfo.ShadingNormal);
                        if (!connections[tracedShadowRayCount].Throughput.IsBlack())
                        {
                            connections[tracedShadowRayCount].Pdf *= lightStrategyPdf;
                            tracedShadowRayCount++;
                        }
                    }
                }

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    PathState = GenericPathSamplerState.Connection;
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= f / fPdf;


                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {

                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    else
                    {
                        PathState = GenericPathSamplerState.Connection;
                        return;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                this.PathState = GenericPathSamplerState.Sampling;
#if VERBOSE
            }
            catch (Exception ex)
            {
                Console.WriteLine("Advance path exception");
                Console.WriteLine("Error triangle {0}", currentTriangleIndex);
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);

            }
#endif
        }
示例#42
0
        public void EvaluatePhoton(IRayEngineScene scen, float u0, float u1, float u2, float u3, float u4, out LightSample result)
        {
            result = new LightSample();
            var scene = (RayEngineScene)scen;
            float b0, b1, b2;
            Point orig;
            scene.Triangles[triangleIndex].Sample(scene.Vertices, u0, u1, out orig, out b0, out b1, out b2);

            // Ray direction
            var sampleN = this.TriangleNormal;
            Vector dir = MC.UniformSampleSphere(u2, u3);
            float RdotN = Normal.Dot(ref dir, ref sampleN);
            if (RdotN < 0f)
            {
                dir *= -1f;
                RdotN = -RdotN;
            }

            result.LightRay = new RayData(ref orig, ref dir);

            result.Pdf = (MathLab.INVTWOPI / area) * 1f / RdotN;

            result.Spectrum = this.lightSpectra;

        }
示例#43
0
        public void EvaluateShadow(Core.Surface.BaseBxdf bsdfSample, float u0, float u1, float u2, ref LightSample result)
        {
#if VERBOSE
            try
            {
#endif
                if (result == null)
                    result = new LightSample();

                if (true)
                {
                    var wi = MC.CosineSampleHemisphere(u1, u2);

                    wi = bsdfSample.Frame.ToWorld(ref wi);

                    result.LightRay = new RayData(ref bsdfSample.HitPoint.HitPoint, ref wi, 1e-4f, float.MaxValue);
                    result.Distance = 1e4f;
                    result.Spectrum = Le(ref wi);
                    result.Pdf = wi.z * MathLab.INVPI;

                    //var i = ((RgbSpectrumInfo) result.Spectrum).y();
                    //result.Pdf *= i;

                }
                else
                {
                    Vector wi = MC.UniformSampleSphere(u0, u1);

                    result.LightRay = new RayData(ref bsdfSample.HitPoint.HitPoint, ref wi, 1e-4f, float.MaxValue);
                    result.Pdf = 1f / (4f * MathLab.M_PI);
                    result.Spectrum = Le(ref wi);

                    //var i = ((RgbSpectrumInfo)result.Spectrum).y();
                    //result.Pdf *= i;
                }
#if VERBOSE
            }
            catch (Exception ex)
            {
                Tracer.TraceLine(ex.Message);
                Tracer.TraceLine(ex.StackTrace);
                throw;
            }
#endif
        }