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 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 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; }