Example #1
0
        private Vector EstimateColorWithPhotonmapping(int x, int y, Random rand, Photonmap photonmap)
        {
            Ray    primaryRay  = data.Camera.GetPrimaryRay(x, y);
            float  cosAtCamera = Vector.Dot(primaryRay.Direction, this.data.Camera.Forward);
            Vector pathWeight  = new Vector(1, 1, 1) * cosAtCamera;

            var eyePoint = this.intersectionFinder.GetIntersectionPoint(primaryRay);

            Vector pixelColor = new Vector(0, 0, 0);

            if (eyePoint != null)
            {
                if (eyePoint.IsLocatedOnLightSource)
                {
                    return(eyePoint.Emission);
                }

                pathWeight = Vector.Mult(pathWeight, DiffuseBrdf.Evaluate(eyePoint));

                //Direct Lighting
                var lightPoint = data.LightSource.GetRandomPointOnLightSource(rand);
                if (IsVisible(eyePoint.Position, lightPoint.Position))
                {
                    pixelColor += Vector.Mult(pathWeight, lightPoint.Color * GeometryTerm(eyePoint, lightPoint) / lightPoint.PdfA);
                }

                //Final Gathering
                Vector newDirection = DiffuseBrdf.SampleDirection(eyePoint.Normal, rand);
                pathWeight = pathWeight * Vector.Dot(eyePoint.Normal, newDirection) / DiffuseBrdf.PdfW(eyePoint.Normal, newDirection);
                var finalGatherPoint = this.intersectionFinder.GetIntersectionPoint(new Ray(eyePoint.Position, newDirection));

                if (finalGatherPoint != null)
                {
                    //100000 3000 1000
                    float searchRadius   = 0.00634257728f * 2;//0.0383904837f;//0.065260686f;
                    var   photons        = photonmap.SearchPhotons(finalGatherPoint, searchRadius);
                    float kernelFunction = 1.0f / (searchRadius * searchRadius * (float)Math.PI);
                    foreach (var photon in photons)
                    {
                        pixelColor += Vector.Mult(pathWeight, Vector.Mult(DiffuseBrdf.Evaluate(finalGatherPoint), photon.PathWeight) * kernelFunction);
                    }
                }
            }

            return(pixelColor);
        }
        private Vector EstimateColorWithPathtracing(int x, int y, Random rand)
        {
            Ray    primaryRay  = data.Camera.GetPrimaryRay(x, y);
            float  cosAtCamera = Vector.Dot(primaryRay.Direction, this.data.Camera.Forward);
            Vector pathWeight  = new Vector(1, 1, 1) * cosAtCamera;

            Ray ray = primaryRay;

            int maxPathLength = 5;

            for (int i = 0; i < maxPathLength; i++)
            {
                var point = this.intersectionFinder.GetIntersectionPoint(ray);
                if (point == null)
                {
                    return(new Vector(0, 0, 0));
                }

                if (point.IsLocatedOnLightSource && Vector.Dot(point.Normal, -ray.Direction) > 0)
                {
                    pathWeight = Vector.Mult(pathWeight, point.Emission);
                    return(pathWeight);
                }

                //Abbruch mit Russia Rollete
                float continuationPdf = Math.Min(1, point.Color.Max());
                if (rand.NextDouble() >= continuationPdf)
                {
                    return(new Vector(0, 0, 0)); // Absorbation
                }
                Vector newDirection = DiffuseBrdf.SampleDirection(point.Normal, rand);
                pathWeight = Vector.Mult(pathWeight * Vector.Dot(point.Normal, newDirection) / DiffuseBrdf.PdfW(point.Normal, newDirection), DiffuseBrdf.Evaluate(point)) / continuationPdf;
                ray        = new Ray(point.Position, newDirection);
            }

            return(new Vector(0, 0, 0));
        }
Example #3
0
        private List <Photon> TracePhoton(Random rand)
        {
            var    lightPoint = this.lightSource.GetRandomPointOnLightSource(rand);
            Vector direction  = DiffuseBrdf.SampleDirection(lightPoint.Normal, rand);
            float  pdfW       = DiffuseBrdf.PdfW(lightPoint.Normal, direction);
            float  lambda     = Vector.Dot(lightPoint.Normal, direction);
            Vector pathWeight = lightPoint.Color * lambda / (lightPoint.PdfA * pdfW);
            Ray    ray        = new Ray(lightPoint.Position, direction);
            //PhotonType type = PhotonType.None;

            int maxPathLength = 5;

            List <Photon> photons = new List <Photon>();

            for (int i = 0; i < maxPathLength; i++)
            {
                var point = this.intersectionFinder.GetIntersectionPoint(ray);
                if (point == null)
                {
                    return(photons);
                }

                photons.Add(new Photon(point.Position, point.Normal, pathWeight / this.photonCount, ray.Direction));

                //Abbruch mit Russia Rollete
                float continuationPdf = Math.Min(1, point.Color.Max());
                if (rand.NextDouble() >= continuationPdf)
                {
                    return(photons); // Absorbation
                }
                Vector newDirection = DiffuseBrdf.SampleDirection(point.Normal, rand);
                pathWeight = Vector.Mult(pathWeight * Vector.Dot(point.Normal, newDirection) / DiffuseBrdf.PdfW(point.Normal, newDirection), DiffuseBrdf.Evaluate(point)) / continuationPdf;
                ray        = new Ray(point.Position, newDirection);
            }

            return(photons);
        }
Example #4
0
        private Vector[,] EstimateFrameWithLightracing(int width, int height, Random rand)
        {
            int lightPathsPerIteration = width * height;
            int maxPathLength          = 5;

            Vector[,] frame = new Vector[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    frame[x, y] = new Vector(0, 0, 0);
                }
            }

            for (int j = 0; j < lightPathsPerIteration; j++)
            {
                //Sample Position on Lightsource
                var point = data.LightSource.SampleRandomPointOnLightSource(rand);

                //Pathweight
                Vector pathWeight = new Vector(1, 1, 1) * data.LightSource.EmissionPerArea / data.LightSource.PdfA;

                //Connect Point on Lightsource with Camera
                var c = TryToConnectPointWithCamera(point, pathWeight, lightPathsPerIteration);
                if (c != null)
                {
                    frame[c.PixelX, c.PixelY] += c.PathContribution;
                }

                //Sample Direction from Point on LightSource into scene. Use the diffuse Brdf
                Vector direction = DiffuseBrdf.SampleDirection(point.Normal, rand); //Direct vom Point on Light into some point in scene
                float  pdfW      = DiffuseBrdf.PdfW(point.Normal, direction);       //PDF with Respect to Solid Angle from 'direction'

                //New Pathweight after sampling direction
                float cosAtPoint = Math.Max(0, Vector.Dot(point.Normal, direction));
                pathWeight *= cosAtPoint / pdfW;

                Ray ray = new Ray(point.Position, direction);

                for (int k = 1; k < maxPathLength; k++)
                {
                    //Get next intersectionpoint with scene starting from old point-Position
                    point = this.intersectionFinder.GetIntersectionPoint(ray);
                    if (point == null)
                    {
                        break;                //Break Light-Path-Creation
                    }
                    //Connect Point in scene with Camera
                    c = TryToConnectPointWithCamera(point, pathWeight, lightPathsPerIteration);
                    if (c != null)
                    {
                        frame[c.PixelX, c.PixelY] += c.PathContribution;
                    }

                    //The Lightsource dosn't reflect light
                    if (point.IsLocatedOnLightSource)
                    {
                        break;
                    }

                    //Break with Russia Rollete
                    float continuationPdf = Math.Min(1, point.Color.Max());
                    if (rand.NextDouble() >= continuationPdf)
                    {
                        break; // Absorbation
                    }
                    //Go ahead with lighttracing after connection with camera
                    direction  = DiffuseBrdf.SampleDirection(point.Normal, rand);
                    pdfW       = DiffuseBrdf.PdfW(point.Normal, direction);
                    cosAtPoint = Math.Max(0, Vector.Dot(point.Normal, direction));
                    pathWeight = Vector.Mult(pathWeight, DiffuseBrdf.Evaluate(point)) * cosAtPoint / (pdfW * continuationPdf);
                    ray        = new Ray(point.Position, direction);
                }
            }

            return(frame);
        }
Example #5
0
        private Vector EstimateColorWithPathtracingWithNextEventEstimation(int x, int y, Random rand)
        {
            //This is the sum from all Pathcontributions from all Pathlenghts up to maxPathLength
            //This means Contribution(C L) + Contribution(C D L) + Contribution(C D D L) + Contribution(C D D D L) + Contribution(C D D D D L)
            //For Each Pathlength-Step, the Contribution from Brdf-Sampling and Lightsource-Sampling is added but only one from this two Sampling-Methods
            //will create a Contribution != 0. If you hit the Lightsource, then you only get the BrdfSampling-Contribution. The LightSource-Sampling-Contribution
            //will be zero because if your running point is on the light and the light don't reflect any light, then you don't can create any more Lightpoints
            //If you are on a Point in the Scene (Not Lightsoure) then only the Contribution from Lightsource-Sampling can be greater zero. The Brdf-Sampling
            //Contribution (Pathtracing) will be zero.
            Vector contributionSum = new Vector(0, 0, 0);

            Ray    primaryRay  = data.Camera.GetPrimaryRay(x, y);
            float  cosAtCamera = Vector.Dot(primaryRay.Direction, this.data.Camera.Forward);
            Vector pathWeight  = new Vector(1, 1, 1) * cosAtCamera;

            Ray   ray  = primaryRay;
            float pdfW = data.Camera.PdfWForPrimaryRayDirectionSampling(ray.Direction); //This will store the PdfW and Contination Pdf, which was used for Brdf-Sampling

            int maxPathLength = 5;

            for (int i = 0; i < maxPathLength; i++)
            {
                IntersectionPoint point = this.intersectionFinder.GetIntersectionPoint(ray);
                if (point == null)
                {
                    break;                //Ray leave the scene
                }
                //Try to add Contribution from Brdf-Sampling (This Brdf-Sampling is also called Pathtracing because you do this for every Pathpoint)
                if (point.IsLocatedOnLightSource && Vector.Dot(point.Normal, -ray.Direction) > 0)
                {
                    //This is the PdfA on the LightPoint, if you would use LightSource-Sampling, to reach from lastPoint(ray.Origin) to current point 'point'
                    float pdfAFromLightSourceSampling = data.LightSource.PdfA;

                    //This is the PdfA on the LightPoint, which you get from BrdfSampling to reach rom lastPoint(ray.Origin) to current point 'point'
                    float pdfAFromBrdfSampling = pdfW * Vector.Dot(point.Normal, -ray.Direction) / (ray.Origin - point.Position).SqrLength();

                    //We have used Brdf-Sampling. So the pdfAFromBrdfSampling is in the numerator
                    float  misFactor = pdfAFromBrdfSampling / (pdfAFromLightSourceSampling + pdfAFromBrdfSampling);
                    Vector contributionFromBrdfSampling = Vector.Mult(pathWeight, point.Emission) * misFactor;

                    contributionSum += contributionFromBrdfSampling;

                    break; //The light don't reflect any light. So stop here with Pathtracing
                }

                //Try to add Contribution from Lightsource-Sampling (This is the Next Event Estimation-Sampling)
                contributionSum += GetContributionFromLightSourceSampling(point, rand, pathWeight);

                //Stop with Russia Rollete
                float continuationPdf = Math.Min(1, point.Color.Max());
                if (rand.NextDouble() >= continuationPdf)
                {
                    break; // Absorbation
                }
                //Sample Direction and try to hit to lightSource
                Vector direction = DiffuseBrdf.SampleDirection(point.Normal, rand);
                pdfW = DiffuseBrdf.PdfW(point.Normal, direction) * continuationPdf;
                float cosAtPoint = Math.Max(0, Vector.Dot(point.Normal, direction));

                pathWeight = Vector.Mult(pathWeight, DiffuseBrdf.Evaluate(point)) * cosAtPoint / pdfW; //New Pathweight after Brdf-Sampling
                ray        = new Ray(point.Position, direction);
            }

            return(contributionSum);
        }