public void TestFlatRender() { Color sphereColor = new Color(1f, 2f, 3f); Sphere sphere = new Sphere( transformation: Transformation.Translation(new Vec(2f, 0f, 0f)) * Transformation.Scaling(new Vec(0.2f, 0.2f, 0.2f)), material: new Material(Brdf: new DiffuseBRDF(pig: new UniformPigment(sphereColor))) ); HdrImage image = new HdrImage(3, 3); OrthogonalCamera camera = new OrthogonalCamera(); ImageTracer tracer = new ImageTracer(image, camera); World world = new World(); world.addShape(sphere); FlatRender renderer = new FlatRender(world); tracer.fireAllRays(renderer); Assert.True(image.getPixel(0, 0).isClose(Constant.Black), "TestFlatRender failed - Assert 1/9"); Assert.True(image.getPixel(1, 0).isClose(Constant.Black), "TestFlatRender failed - Assert 2/9"); Assert.True(image.getPixel(2, 0).isClose(Constant.Black), "TestFlatRender failed - Assert 3/9"); Assert.True(image.getPixel(0, 1).isClose(Constant.Black), "TestFlatRender failed - Assert 4/9"); Assert.True(image.getPixel(1, 1).isClose(sphereColor), "TestFlatRender failed - Assert 5/9"); Assert.True(image.getPixel(2, 1).isClose(Constant.Black), "TestFlatRender failed - Assert 6/9"); Assert.True(image.getPixel(0, 2).isClose(Constant.Black), "TestFlatRender failed - Assert 7/9"); Assert.True(image.getPixel(1, 2).isClose(Constant.Black), "TestFlatRender failed - Assert 8/9"); Assert.True(image.getPixel(2, 2).isClose(Constant.Black), "TestFlatRender failed - Assert 9/9"); }
public void TestPointLightRenderer1() { World world = new World(); world.addPointLight(new PointLight(new Point(10f, 10f, 10f), Constant.White)); world.addShape(new Sphere(Transformation.Translation(new Vec(10f, 10f, 10f)))); Sphere sphere = new Sphere( transformation: Transformation.Translation(new Vec(2f, 0f, 0f)) * Transformation.Scaling(new Vec(0.2f, 0.2f, 0.2f)), material: new Material(Brdf: new DiffuseBRDF(pig: new UniformPigment(Constant.White)))); HdrImage image = new HdrImage(3, 3); OrthogonalCamera camera = new OrthogonalCamera(); ImageTracer tracer = new ImageTracer(i: image, c: camera); world.addShape(sphere); PointLightRender renderer = new PointLightRender(world); tracer.fireAllRays(renderer); Assert.True(image.getPixel(0, 0).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 1/9"); Assert.True(image.getPixel(1, 0).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 2/9"); Assert.True(image.getPixel(2, 0).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 3/9"); Assert.True(image.getPixel(0, 1).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 4/9"); Assert.True(image.getPixel(1, 1).isClose(renderer.ambientColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 5/9"); Assert.True(image.getPixel(2, 1).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 6/9"); Assert.True(image.getPixel(0, 2).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 7/9"); Assert.True(image.getPixel(1, 2).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 8/9"); Assert.True(image.getPixel(2, 2).isClose(renderer.backgroundColor), "TestPointLight rendered failed (light source shielded by a sphere) - Assert 9/9"); }
public void TestImageCoverage() { HdrImage image = new HdrImage(4, 2); PerspectiveCamera camera = new PerspectiveCamera(); ImageTracer tracer = new ImageTracer(image, camera); tracer.fireAllRays((Ray r) => new Color(1f, 2f, 3f)); for (int row = 0; row < image.height; row++) { for (int col = 0; col < image.width; col++) { Assert.True(image.getPixel(col, row).isClose(new Color(1.0f, 2.0f, 3.0f)), $"TestImageCoverage failed - Assert row={row}, col={col}"); } } } //end of function
public static void ExecuteRender(string file, int width, int height, string pfmFile, string ldrFile, int spp, char rend, Dictionary<string, float> variables, float factor, float gamma, int maxDepth, int nRays, int rrLimit) { Console.WriteLine($"File describing the scene: {file}"); Console.WriteLine($"Image size: {width}x{height}"); Console.WriteLine($"Output PFM-file: {pfmFile}"); Console.WriteLine($"Output LDR-file: {ldrFile}"); Console.WriteLine($"Samples-per-pixel (antialiasing): {spp}"); // Console.WriteLine($"Maximum ray depth: {maxDepth}"); // Console.WriteLine($"Number of sampled rays: {nRays}"); // Console.WriteLine($"Russian Roulette Lower Limit: {rrLimit}"); Console.WriteLine("User-defined overridden variables"); if (variables.Count == 0) Console.WriteLine(" - No Variables"); foreach (var item in variables) { Console.WriteLine($" - {item.Key} = {item.Value}"); } Scene scene = new Scene(); using (FileStream inputSceneStream = File.OpenRead(file)) { try { scene = Scene.parseScene(inputFile: new InputStream(stream: inputSceneStream, fileName: file), variables: variables); } catch (GrammarError e) { SourceLocation loc = e.sourceLocation; Console.WriteLine($"{loc.fileName}:{loc.lineNum}:{loc.colNum}: {e.Message}"); return; } } HdrImage image = new HdrImage(width, height); // Run the ray-tracer ImageTracer tracer = new ImageTracer(i: image, c: scene.camera, sps: (int)MathF.Sqrt(spp)); Render renderer; if (rend == 'o') { Console.WriteLine("\nUsing on/off renderer:"); renderer = new OnOffRender(world: scene.world, background: CC.Black); } else if (rend == 'f') { Console.WriteLine("\nUsing flat renderer:"); renderer = new FlatRender(world: scene.world, background: CC.Black); } else if (rend == 'r') { Console.WriteLine("\nUsing a path tracer:"); renderer = new PathTracer(world: scene.world, numOfRays: nRays, maxDepth: maxDepth, russianRouletteLimit: rrLimit); Console.WriteLine($">>>> Max depth: {((PathTracer)renderer).maxDepth}"); Console.WriteLine($">>>> Russian Roulette Limit: {((PathTracer)renderer).russianRouletteLimit}"); Console.WriteLine($">>>> Number of rays: {((PathTracer)renderer).numOfRays}"); } else if (rend == 'p') { Console.WriteLine("\nUsing a point-light tracer: "); renderer = new PointLightRender(world: scene.world, background: CC.Black); Console.WriteLine($">> Ambient color: {((PointLightRender)renderer).ambientColor}"); } else { Console.WriteLine($"Unknown renderer: {rend}"); return; } Stopwatch sw = new Stopwatch(); sw.Start(); tracer.fireAllRays(renderer); Console.WriteLine("Saving in pfm format..."); using (FileStream outpfmstream = File.OpenWrite(pfmFile)) { image.savePfm(outpfmstream); Console.WriteLine($"Image saved in {pfmFile}"); } Convert.ExecuteConvert(pfmFile, ldrFile, factor, gamma, null); sw.Stop(); TimeSpan ts = sw.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine("\nRun Time: " + elapsedTime); Console.WriteLine("See you next time!\n"); } //RenderScene
public static void ExecuteDemo(int width, int height, int angle, bool orthogonal, string pfmFile, string ldrFile, int scene, float?luminosity, int spp, char rendType) { Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("Starting Demo with these parameters:\n"); Console.WriteLine("Width: " + width + " pixels"); Console.WriteLine("Height: " + height + " pixels"); Console.WriteLine("Angle: " + angle + " degrees"); Console.WriteLine(orthogonal ? "Orthogonal Camera" : "Perspective Camera"); Console.WriteLine("pfmFile: " + pfmFile); Console.WriteLine("ldrFile: " + ldrFile); Console.WriteLine("Samples per pixel: " + spp); Console.WriteLine("Render type: " + dictRend[rendType]); Console.WriteLine("\n"); HdrImage image = new HdrImage(width, height); // Camera initialization Console.WriteLine("Creating the camera..."); // var cameraTransf = Transformation.RotationZ(Utility.DegToRad(angle)) * Transformation.Translation(-2.0f, 0.0f, 0.5f) * Tsf.RotationY(Utility.DegToRad(15)); var cameraTransf = Transformation.Translation(-2.0f, 0.0f, 0.0f); Camera camera; if (orthogonal) { camera = new OrthogonalCamera(aspectRatio: (float)width / height, transformation: cameraTransf); } else { camera = new PerspectiveCamera(aspectRatio: (float)width / height, transformation: cameraTransf); } // Default value on/off renderer Render?renderer = null; Console.WriteLine("Creating the scene..."); World world = new World(); List <float> Vertices = new List <float>() { -0.5f, 0.5f }; switch (scene) { case 1: //One sphere for each vertex of the cube foreach (var x in Vertices) { foreach (var y in Vertices) { foreach (var z in Vertices) { world.addShape(new Sphere(Tsf.Translation(new Vec(x, y, z)) * Tsf.Scaling(new Vec(0.1f, 0.1f, 0.1f)))); } // z } // y } // x //Adding two more spheres to break simmetry world.addShape(new Sphere(Tsf.Translation(new Vec(0f, 0f, -0.5f)) * Tsf.Scaling(0.1f))); world.addShape(new Sphere(Tsf.Translation(new Vec(0f, 0.5f, 0f)) * Tsf.Scaling(0.1f))); break; case 2: HdrImage img = new HdrImage(); string inputpfm = "Texture/CokeTexture.pfm"; using (FileStream inputStream = File.OpenRead(inputpfm)) { img.readPfm(inputStream); Console.WriteLine($"Texture {inputpfm} has been correctly read from disk."); } Material groundM = new Material(new DiffuseBRDF(new CheckeredPigment(CC.BrightGreen, CC.Orange, 4)), new UniformPigment(CC.Black)); world.addShape(CC.SKY); world.addShape(new Plane(Tsf.Translation(0f, 0f, -3f), groundM)); world.addShape( new Cylinder( transformation: Tsf.Translation(.5f, -1f, -1f) * Transformation.Scaling(.6f, 0.6f, 1.3f) * Tsf.RotationY(Utility.DegToRad(45)), material: new Material( Brdf: new DiffuseBRDF(new ImagePigment(img)) //EmittedRadiance: new UniformPigment(CC.Red)// new ImagePigment(img) ) ) ); world.addShape( new Cylinder( transformation: Tsf.Translation(.5f, 1f, -1f) * Transformation.Scaling(.6f, 0.6f, 1.3f) * Tsf.RotationY(Utility.DegToRad(-45)), material: new Material( Brdf: new DiffuseBRDF(new ImagePigment(img)) //EmittedRadiance: new UniformPigment(CC.Red)// new ImagePigment(img) ) ) ); break; case 3: PCG pcg = new PCG(); Material sph1Mat = new Material(new DiffuseBRDF(new UniformPigment(CC.BlueChill))); Material sph2Mat = new Material(new DiffuseBRDF(new UniformPigment(Color.random()))); Material boxMat = new Material(new DiffuseBRDF(new UniformPigment(CC.BrightGreen))); world.addShape(new Sphere(Tsf.Scaling(500f), CC.skyMat)); world.addShape(new Plane(Tsf.Translation(0f, 0f, -1f), CC.groundMat)); world.addShape(new CSGUnion(new Sphere(Transformation.Translation(0.5f, -2.6f, 1f) * Transformation.Scaling(0.6f), sph2Mat), new Box(new Point(0f, -2.25f, 0.9f), new Point(1f, -3.25f, 1.8f), null, boxMat))); world.addShape(new Sphere(Tsf.Translation(3f, 5f, 1.6f) * Tsf.Scaling(2.0f, 4.0f, 2.0f), CC.refMat)); world.addShape(new Sphere(Tsf.Translation(4f, -1f, 1.3f) * Tsf.Scaling(1.0f), sph1Mat)); world.addShape(new Sphere(Tsf.Translation(-4f, -0.5f, 1f) * Tsf.Scaling(2f), sph2Mat)); break; case 4: Material mat = new Material(null, new UniformPigment(new Color(10f, 10f, 10f))); world.addShape(CC.SKY); world.addShape(new Plane(Tsf.Scaling(-3f, 0f, 0f) * Tsf.RotationY(Utility.DegToRad(270)), mat)); world.addShape(CC.wikiShape(Tsf.RotationZ(Utility.DegToRad(23)))); // world.addShape(CC.wikiShape(Tsf.RotationZ(Utility.DegToRad(45)))); break; case 5: Material skyM = new Material(new DiffuseBRDF(new UniformPigment(CC.SkyBlue)), new UniformPigment(CC.SkyBlue)); Material checkered = new Material(new DiffuseBRDF(new CheckeredPigment(CC.Blue, CC.Yellow)), new UniformPigment(CC.Black)); Material ground = new Material(new DiffuseBRDF(new CheckeredPigment(CC.LightRed, CC.Orange)), new UniformPigment(CC.Black)); world.addShape(new Sphere(Tsf.Scaling(500f), skyM)); world.addShape(new Cylinder(Tsf.Translation(0f, 2f, -0.5f) * Tsf.Scaling(0.5f), checkered)); world.addShape(new Cone(r: 0.5f, material: checkered)); world.addShape(new Plane(Tsf.Translation(0f, 0f, -1f), ground)); break; default: break; } switch (rendType) { case 'o': renderer = new OnOffRender(world); break; case 'f': renderer = new FlatRender(world); break; case 'p': renderer = new PointLightRender(world); break; case 'r': renderer = new PathTracer(world, CC.Black, new PCG()); break; default: break; } // Ray tracing Console.WriteLine("Rendering the scene..."); var rayTracer = new ImageTracer(image, camera, (int)Math.Sqrt(spp)); if (renderer == null) { renderer = new OnOffRender(world); } rayTracer.fireAllRays(renderer); // Write PFM image Console.WriteLine("Saving in pfm format..."); using (FileStream outpfmstream = File.OpenWrite(pfmFile)) { image.savePfm(outpfmstream); Console.WriteLine($"Image saved in {pfmFile}"); } Convert.ExecuteConvert(pfmFile, ldrFile, Default.factor, Default.gamma, luminosity); sw.Stop(); TimeSpan ts = sw.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine("RunTime " + elapsedTime); }//Demo