Ejemplo n.º 1
0
        private static void calculateAmbientOcclusion(List <LightMap> maps, TrianglePartitioner scene)
        {
            int numPatches = 0;

            foreach (LightMap l in maps)
            {
                numPatches += l.patches.Count;
            }
            Settings.stream.SetProgressBarMaximum(numPatches);

            ParallelOptions opts = new ParallelOptions();

            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            Random generator = new Random();

            foreach (LightMap l in maps)
            {
                Parallel.ForEach(l.patches, opts, delegate(Patch p, ParallelLoopState state)
                {
                    if (abort)
                    {
                        state.Stop();
                    }

                    Random localGenerator;
                    lock (generator)
                    {
                        localGenerator = new Random(generator.Next());
                    }

                    for (int sample = 0; sample < 64 /*Settings.ambientOcclusionSamples*/; sample++)
                    {
                        double randomA = localGenerator.NextDouble();
                        double randomB = localGenerator.NextDouble();

                        //http://mathworld.wolfram.com/SpherePointPicking.html
                        double theta = 2 * Math.PI * randomA;
                        double phi   = Math.Acos(2 * randomB - 1);

                        Vector3 randomDirection = new Vector3(Settings.ambientRayLength * (float)(Math.Cos(theta) * Math.Sin(phi)),
                                                              Settings.ambientRayLength * (float)(Math.Sin(theta) * Math.Sin(phi)),
                                                              Settings.ambientRayLength * (float)Math.Cos(phi));

                        if (Vector3.Dot(p.normal, randomDirection) < 0)
                        {
                            randomDirection = -randomDirection;
                        }

                        Triangle throwAway;
                        if (scene.intersection(p.position, randomDirection, out throwAway) > 0)
                        {
                            p.ambientOcclusion += 4;
                        }
                    }
                    Settings.stream.UpdateProgress();
                });

                if (abort)
                {
                    throw new LightmappingAbortedException("Aborted lightmapping while gathering photons.");
                }
            }
        }
Ejemplo n.º 2
0
        private static void gatherPhotons(List <LightMap> maps, PhotonPartitioner photonMap, TrianglePartitioner scene, List <Light> lights)
        {
            int numPatches = 0;

            foreach (LightMap l in maps)
            {
                numPatches += l.patches.Count;
            }
            Settings.stream.SetProgressBarMaximum(numPatches);

            ParallelOptions opts = new ParallelOptions();

            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            foreach (LightMap l in maps)
            {
                Parallel.ForEach(l.patches, opts, delegate(Patch p, ParallelLoopState state)
                {
                    if (abort)
                    {
                        state.Stop();
                    }

                    List <Photon> gather = photonMap.nearest(Settings.neighbourCount, p.position);
                    foreach (Photon photon in gather)
                    {
                        Triangle throwAway;
                        if (scene.intersection(photon.position, p.position - photon.position, out throwAway) < 1.0f)
                        {
                            p.absorbPhoton(photon);
                        }
                    }

                    foreach (Light light in lights)
                    {
                        if (!light.shootsPhotons)
                        {
                            p.ambientLight += light.influence((p.position - light.position).Length) * light.colour;
                        }
                    }

                    //p.incidentLight *= 100;
                    Settings.stream.UpdateProgress();
                });

                if (abort)
                {
                    throw new LightmappingAbortedException("Aborted lightmapping while gathering photons.");
                }
            }
        }
Ejemplo n.º 3
0
        private static List <Photon> firePhotons(List <Light> lights, TrianglePartitioner scene)
        {
            Random random     = new Random();
            int    numPhotons = 0;

            foreach (Light l in lights)
            {
                if (l.shootsPhotons)
                {
                    numPhotons += Settings.numPhotonsPerLight;
                }
            }
            Settings.stream.SetProgressBarMaximum(numPhotons);

            ParallelOptions opts = new ParallelOptions();

            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            List <Photon> photons            = new List <Photon>();
            double        reflectProbability = 0.3;

            /*
             * foreach(Light l in lights)
             * {
             *  if (l.shootsPhotons)
             *  {
             *      for (int i = 0; i < Settings.numPhotonsPerLight; i++)
             *      {
             *          Vector3 direction = l.generateRandomDirection();
             *          Triangle intersectedTriangle;
             *          float distance = scene.intersection(l.position, direction, out intersectedTriangle);
             *          if (distance > 0)
             *          {
             *              Vector3 intersection = l.position + (distance * direction);
             *              photons.Add(new Photon(intersection, direction, l, 1.0f));
             *              float totalDistance = distance;
             *
             *              //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
             *              while (random.NextDouble() > reflectProbability)
             *              {
             *                  direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
             *                  distance = scene.intersection(intersection, direction, out intersectedTriangle);
             *                  //If we don't get a valid intersection, we are done bouncing
             *                  if (distance <= 0) break;
             *
             *                  intersection = intersection + (distance * direction);
             *                  totalDistance += distance;
             *                  photons.Add(new Photon(intersection, direction, l, 1.0f));
             *              }
             *
             *          }
             *          Settings.stream.UpdateProgress();
             *      }
             *  }
             * }
             * //*/
            //*
            Parallel.ForEach(lights, delegate(Light l, ParallelLoopState state)
            {
                if (l.shootsPhotons)
                {
                    List <Photon> newPhotons = new List <Photon>();
                    for (int i = 0; i < Settings.numPhotonsPerLight; i++)
                    {
                        Vector3 direction = l.generateRandomDirection();
                        Triangle intersectedTriangle;
                        float distance = scene.intersection(l.position, direction, out intersectedTriangle);
                        if (distance > 0)
                        {
                            Vector3 intersection = l.position + (distance * direction);
                            newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            float totalDistance = distance;

                            //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
                            while (random.NextDouble() > reflectProbability)
                            {
                                direction = (-2 * Vector3.Dot(direction, intersectedTriangle.normal) * intersectedTriangle.normal) + direction;
                                //direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
                                distance = scene.intersection(intersection, direction, out intersectedTriangle);
                                //If we don't get a valid intersection, we are done bouncing
                                if (distance <= 0)
                                {
                                    break;
                                }

                                intersection   = intersection + (distance * direction);
                                totalDistance += distance;
                                newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            }
                        }
                        if ((i + 1) % 20 == 0)
                        {
                            if (abort)
                            {
                                state.Stop();
                                return;
                            }
                            Settings.stream.UpdateProgress(20);
                        }
                    }
                    lock (photons)
                    {
                        photons.AddRange(newPhotons);
                    }
                }
            });
            //*/

            /*
             * foreach(Light l in lights)
             * {
             *  if (l.shootsPhotons)
             *  {
             *      Parallel.For(0, Settings.numPhotonsPerLight, delegate(int i, ParallelLoopState state)
             *      {
             *          if (abort)
             *          {
             *              state.Stop();
             *          }
             *          List<Photon> newPhotons = new List<Photon>();
             *          Vector3 direction = l.generateRandomDirection();
             *          Triangle intersectedTriangle;
             *          float distance = scene.intersection(l.position, direction, out intersectedTriangle);
             *          if (distance > 0)
             *          {
             *              Vector3 intersection = l.position + (distance * direction);
             *              newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
             *              float totalDistance = distance;
             *
             *              //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
             *              while (random.NextDouble() > reflectProbability)
             *              {
             *                  direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
             *                  distance = scene.intersection(intersection, direction, out intersectedTriangle);
             *                  //If we don't get a valid intersection, we are done bouncing
             *                  if (distance <= 0) break;
             *
             *                  intersection = intersection + (distance * direction);
             *                  totalDistance += distance;
             *                  newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
             *              }
             *
             *          }
             *          Settings.stream.UpdateProgress();
             *          lock (photons)
             *          {
             *              photons.AddRange(newPhotons);
             *          }
             *      });
             *  }
             * }
             * //*/

            if (abort)
            {
                throw new LightmappingAbortedException("Aborted lightmapping while firing photons.");
            }

            return(photons);
        }
        private static void calculateAmbientOcclusion(List<LightMap> maps, TrianglePartitioner scene)
        {
            int numPatches = 0;
            foreach (LightMap l in maps)
            {
                numPatches += l.patches.Count;
            }
            Settings.stream.SetProgressBarMaximum(numPatches);

            ParallelOptions opts = new ParallelOptions();
            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            Random generator = new Random();

            foreach (LightMap l in maps)
            {
                Parallel.ForEach(l.patches, opts, delegate(Patch p, ParallelLoopState state)
                {
                    if (abort)
                    {
                        state.Stop();
                    }

                    Random localGenerator;
                    lock (generator)
                    {
                        localGenerator = new Random(generator.Next());
                    }

                    for (int sample = 0; sample < 64 /*Settings.ambientOcclusionSamples*/; sample++)
                    {
                        double randomA = localGenerator.NextDouble();
                        double randomB = localGenerator.NextDouble();

                        //http://mathworld.wolfram.com/SpherePointPicking.html
                        double theta = 2 * Math.PI * randomA;
                        double phi = Math.Acos(2 * randomB - 1);

                        Vector3 randomDirection = new Vector3(Settings.ambientRayLength * (float)(Math.Cos(theta) * Math.Sin(phi)),
                                                                Settings.ambientRayLength * (float)(Math.Sin(theta) * Math.Sin(phi)),
                                                                Settings.ambientRayLength * (float)Math.Cos(phi));

                        if (Vector3.Dot(p.normal, randomDirection) < 0)
                        {
                            randomDirection = -randomDirection;
                        }

                        Triangle throwAway;
                        if (scene.intersection(p.position, randomDirection, out throwAway) > 0)
                        {
                            p.ambientOcclusion += 4;
                        }
                    }
                    Settings.stream.UpdateProgress();
                });

                if (abort)
                {
                    throw new LightmappingAbortedException("Aborted lightmapping while gathering photons.");
                }
            }
        }
        private static void gatherPhotons(List<LightMap> maps, PhotonPartitioner photonMap, TrianglePartitioner scene, List<Light> lights)
        {
            int numPatches = 0;
            foreach (LightMap l in maps)
            {
                numPatches += l.patches.Count;
            }
            Settings.stream.SetProgressBarMaximum(numPatches);

            ParallelOptions opts = new ParallelOptions();
            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            foreach (LightMap l in maps)
            {
                Parallel.ForEach(l.patches, opts, delegate(Patch p, ParallelLoopState state)
                {
                    if (abort)
                    {
                        state.Stop();
                    }

                    List<Photon> gather = photonMap.nearest(Settings.neighbourCount, p.position);
                    foreach (Photon photon in gather)
                    {
                        Triangle throwAway;
                        if (scene.intersection(photon.position, p.position - photon.position, out throwAway) < 1.0f)
                        {
                            p.absorbPhoton(photon);
                        }
                    }

                    foreach (Light light in lights)
                    {
                        if (!light.shootsPhotons)
                        {
                            p.ambientLight += light.influence((p.position - light.position).Length) * light.colour;
                        }
                    }

                    //p.incidentLight *= 100;
                    Settings.stream.UpdateProgress();
                });

                if (abort)
                {
                    throw new LightmappingAbortedException("Aborted lightmapping while gathering photons.");
                }
            }
        }
        private static List<Photon> firePhotons(List<Light> lights, TrianglePartitioner scene)
        {
            Random random = new Random();
            int numPhotons = 0;
            foreach (Light l in lights)
            {
                if (l.shootsPhotons)
                {
                    numPhotons += Settings.numPhotonsPerLight;
                }
            }
            Settings.stream.SetProgressBarMaximum(numPhotons);

            ParallelOptions opts = new ParallelOptions();
            opts.MaxDegreeOfParallelism = Settings.maxThreads;

            List<Photon> photons = new List<Photon>();
            double reflectProbability = 0.3;
            /*
            foreach(Light l in lights)
            {
                if (l.shootsPhotons)
                {
                    for (int i = 0; i < Settings.numPhotonsPerLight; i++)
                    {
                        Vector3 direction = l.generateRandomDirection();
                        Triangle intersectedTriangle;
                        float distance = scene.intersection(l.position, direction, out intersectedTriangle);
                        if (distance > 0)
                        {
                            Vector3 intersection = l.position + (distance * direction);
                            photons.Add(new Photon(intersection, direction, l, 1.0f));
                            float totalDistance = distance;

                            //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
                            while (random.NextDouble() > reflectProbability)
                            {
                                direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
                                distance = scene.intersection(intersection, direction, out intersectedTriangle);
                                //If we don't get a valid intersection, we are done bouncing
                                if (distance <= 0) break;

                                intersection = intersection + (distance * direction);
                                totalDistance += distance;
                                photons.Add(new Photon(intersection, direction, l, 1.0f));
                            }

                        }
                        Settings.stream.UpdateProgress();
                    }
                }
            }
            //*/
            //*
            Parallel.ForEach(lights, delegate(Light l, ParallelLoopState state)
            {
                if (l.shootsPhotons)
                {
                    List<Photon> newPhotons = new List<Photon>();
                    for(int i = 0; i < Settings.numPhotonsPerLight; i++)
                    {
                        Vector3 direction = l.generateRandomDirection();
                        Triangle intersectedTriangle;
                        float distance = scene.intersection(l.position, direction, out intersectedTriangle);
                        if (distance > 0)
                        {
                            Vector3 intersection = l.position + (distance * direction);
                            newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            float totalDistance = distance;

                            //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
                            while (random.NextDouble() > reflectProbability)
                            {
                                direction = (-2 * Vector3.Dot(direction, intersectedTriangle.normal) * intersectedTriangle.normal) + direction;
                                //direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
                                distance = scene.intersection(intersection, direction, out intersectedTriangle);
                                //If we don't get a valid intersection, we are done bouncing
                                if (distance <= 0) break;

                                intersection = intersection + (distance * direction);
                                totalDistance += distance;
                                newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            }

                        }
                        if ((i + 1) % 20 == 0)
                        {
                            if (abort)
                            {
                                state.Stop();
                                return;
                            }
                            Settings.stream.UpdateProgress(20);
                        }
                    }
                    lock (photons)
                    {
                        photons.AddRange(newPhotons);
                    }
                }
            });
            //*/
            /*
            foreach(Light l in lights)
            {
                if (l.shootsPhotons)
                {
                    Parallel.For(0, Settings.numPhotonsPerLight, delegate(int i, ParallelLoopState state)
                    {
                        if (abort)
                        {
                            state.Stop();
                        }
                        List<Photon> newPhotons = new List<Photon>();
                        Vector3 direction = l.generateRandomDirection();
                        Triangle intersectedTriangle;
                        float distance = scene.intersection(l.position, direction, out intersectedTriangle);
                        if (distance > 0)
                        {
                            Vector3 intersection = l.position + (distance * direction);
                            newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            float totalDistance = distance;

                            //I don't actually care if its unique between threads, threadsafty on this random number is not that big of a deal
                            while (random.NextDouble() > reflectProbability)
                            {
                                direction = Vector3.Transform(direction * -1, Matrix4.CreateFromAxisAngle(intersectedTriangle.normal, (float)Math.PI));
                                distance = scene.intersection(intersection, direction, out intersectedTriangle);
                                //If we don't get a valid intersection, we are done bouncing
                                if (distance <= 0) break;

                                intersection = intersection + (distance * direction);
                                totalDistance += distance;
                                newPhotons.Add(new Photon(intersection, direction, l, 1.0f));
                            }

                        }
                        Settings.stream.UpdateProgress();
                        lock (photons)
                        {
                            photons.AddRange(newPhotons);
                        }
                    });
                }
            }
            //*/

            if (abort)
            {
                throw new LightmappingAbortedException("Aborted lightmapping while firing photons.");
            }

            return photons;
        }