public void Render() { if (sampler != null) { for (int i = 0; i < camera.ScreenWidth; i++) { for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads) { Color pixelColor = new Color(0, 0, 0); List <List <Sample> > subPathSamples = new List <List <Sample> >(); List <Sample> samples = sampler.CreateSamples(); List <LightSample> lightSamples = new List <LightSample>(); if (integrator is PathTraceIntegrator) { lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength); for (int s = 0; s < Constants.MaximalPathLength; s++) { subPathSamples.Add(sampler.CreateSamples()); } foreach (Sample sample in samples) { Ray ray = camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } else { lightSamples = sampler.GetLightSamples(); foreach (Sample sample in samples) { Ray ray = camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } pixelColor.VoidDiv(samples.Count); film.SetPixel(i, j, pixelColor); } } } else { for (int i = 0; i < camera.ScreenWidth; i++) { for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads) { Ray ray = camera.CreateRay(i, j); Color pixelColor = integrator.Integrate(ray, objects, lights, null, null, null); film.SetPixel(i, j, pixelColor); } } } ThreadDone(this, new EventArgs()); }
private Color GetShadeColor(HitRecord record, int currentDepth) { if (record != null && record.Distance > 0 && record.Distance < float.MaxValue) { if (record.Material is MirrorMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Mirror Objects { HitRecord mirrorRecord = objects.Intersect(record.CreateReflectedRay()); return(GetShadeColor(mirrorRecord, ++currentDepth).Mult(record.Material.Ks)); } if (record.Material is RefractiveMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Reflective Objects { float r = Reflectance(record); HitRecord reflectionHit = objects.Intersect(record.CreateReflectedRay()); Color reflectedColor = GetShadeColor(reflectionHit, ++currentDepth).Mult(record.Material.Ks); HitRecord refractedHit = objects.Intersect(CreateRefractedRay(record)); Color refractedColor = GetShadeColor(refractedHit, ++currentDepth).Mult(record.Material.Ks); Color retColor = reflectedColor.Mult(r); retColor.Append(refractedColor.Mult(1 - r)); return(retColor); } if (record.HitObject.Light != null && Constants.IsLightSamplingOn) { return(record.HitObject.Light.LightColor); } Color returnColor = new Color(0, 0, 0); foreach (ILight light in lights) { Color lightColor = new Color(0, 0, 0); if (Constants.IsLightSamplingOn && Constants.NumberOfLightSamples > 0) { List <LightSample> lightSamples = sampler.GetLightSamples(); for (int i = 0; i < Constants.NumberOfLightSamples; i++) { LightSample sample = lightSamples[(int)(random.NextDouble() * lightSamples.Count)]; lightSamples.Remove(sample); light.Sample(record, sample); if (IsVisible(record, sample) && sample.LightColor.Power > 0) { if (!(light is AreaLight)) { lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor)); } else { lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor).Div(sample.Pdf)); } } } returnColor.Append(lightColor.Div(Constants.NumberOfLightSamples)); } if (!(light is AreaLight) && IsVisible(record, light)) { returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint))); } } return(returnColor); } return(new Color(0, 0, 0)); }
public void Render() { stopwatch = new Stopwatch(); stopwatch.Reset(); if (Constants.NumberOfThreads == 1) //One Thread { stopwatch.Start(); ISampler sampler = (ISampler)Activator.CreateInstance(Constants.Sampler); if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0) { Console.WriteLine("Using Supersampling with: " + Constants.NumberOfSamples + " samples!"); for (int i = 0; i < scene.Film.Width; i++) { for (int j = 0; j < scene.Film.Height; j++) { Color pixelColor = new Color(0, 0, 0); List <List <Sample> > subPathSamples = new List <List <Sample> >(); List <LightSample> lightSamples = new List <LightSample>(); List <Sample> samples = sampler.CreateSamples(); if (scene.Integrator is PathTraceIntegrator) { lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength); for (int s = 0; s < Constants.MaximalPathLength; s++) { subPathSamples.Add(sampler.CreateSamples()); } foreach (Sample sample in samples) { Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } else { lightSamples = sampler.GetLightSamples(); foreach (Sample sample in samples) { Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } pixelColor.VoidDiv(samples.Count); scene.Film.SetPixel(i, j, pixelColor); } } } else { for (int i = 0; i < scene.Film.Width; i++) { for (int j = 0; j < scene.Film.Height; j++) { Ray ray = scene.Camera.CreateRay(i, j); Color color = scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, null, null, null); scene.Film.SetPixel(i, j, color); } } } stopwatch.Stop(); Debug.WriteLine("Finished rendering in: " + stopwatch.ElapsedMilliseconds + " ms."); Tonemapper.SaveImage("C:\\Test\\" + scene.FileName, scene.Film); } else //More than 1 thread { if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0) { Debug.WriteLine("Start rendering with: " + Constants.NumberOfThreads + " Threads"); stopwatch.Start(); finishedThreads = 0; for (int i = 0; i < Constants.NumberOfThreads; i++) { ISampler sampler = new StratifiedSampler(); MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights, scene.Camera, scene.Film); renderer.ThreadDone += HandleThreadDone; Thread t = new Thread(renderer.Render); t.Start(); } } else { stopwatch.Start(); finishedThreads = 0; for (int i = 0; i < Constants.NumberOfThreads; i++) { MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights, scene.Camera, scene.Film); renderer.ThreadDone += HandleThreadDone; Thread t = new Thread(renderer.Render); t.Start(); } } } }