예제 #1
0
        public IEnumerable <Vector2> GetPath(Vector2 start, Vector2 end)
        {
            _excludedContours = new List <int>();
            var result = new List <Vector2>();

            _currentPoint = start;
            _goal         = end;
            _tracer       = new PathTracer(_contours, _goal, _excludedContours);
            do
            {
                result.Add(_currentPoint);
                List <IntersectedContour> intersectedContours = Utils.GetIntersectedContours(_currentPoint, _goal, _contours);
                if (intersectedContours.Count == 0)
                {
                    break;
                }

                intersectedContours.Sort(SortByDistance);
                var contour = intersectedContours.FirstOrDefault(item => _excludedContours.IndexOf(item.Contour.Id) < 0);
                if (contour == null)
                {
                    throw new Exception("Can't find path because all contoures are excluded!");
                }
                _currentPoint = contour.IntersectionPoint;
                result.Add(_currentPoint);
                _currentPoint = _tracer.Trace(_currentPoint, result, contour.Contour);
            } while (true);

            result.Add(_goal);
            return(result);
        }
예제 #2
0
        public void TestPathTracer()
        {
            PCG pcg = new PCG();

            for (int i = 0; i < 5; i++)
            {
                World world = new World();

                float    emittedRadiance   = pcg.randomFloat();
                float    reflectance       = pcg.randomFloat();
                Material enclosureMaterial = new Material(
                    Brdf: new DiffuseBRDF(pig: new UniformPigment(new Color(1f, 1f, 1f) * reflectance)),
                    EmittedRadiance: new UniformPigment(new Color(1f, 1f, 1f) * emittedRadiance)
                    );

                world.addShape(new Sphere(material: enclosureMaterial));

                PathTracer pathTracer = new PathTracer(
                    world: world,
                    pcg: pcg,
                    numOfRays: 1,
                    maxDepth: 100,
                    russianRouletteLimit: 101
                    );

                Ray   ray      = new Ray(origin: new Point(0f, 0f, 0f), dir: new Vec(1f, 0f, 0f));
                Color color    = pathTracer.computeRadiance(ray);
                float expected = emittedRadiance / (1.0f - reflectance);
                Assert.True(Utility.areClose(expected, color.r, 1e-3f), $"TestPathTracer failed - Assert i={i}, 1/3");
                Assert.True(Utility.areClose(expected, color.g, 1e-3f), $"TestPathTracer failed - Assert i={i}, 2/3");
                Assert.True(Utility.areClose(expected, color.b, 1e-3f), $"TestPathTracer failed - Assert i={i}, 3/3");
            }
        }
        static void Main(string[] args)
        {
            int nx = 300;
            int ny = 300;
            int ns = 50;

            var(world, cam) = Scenes.CornellScene("../../../../SampleObj/teapot.obj", new SunsetquestRandom(), nx, ny);

            var worldBVH = new BVH(world);
            var wl       = new IHitable[] { worldBVH };

            var  pathTracer    = new PathTracer(nx, ny, ns, false);
            uint totalRayCount = 0;

            sw.Start();
            var image = pathTracer.RenderScene(wl, cam, ref totalRayCount, (pcComplete => Console.WriteLine($"{pcComplete}%")));

            sw.Stop();
            image.Save("test.png");
            float seconds = sw.ElapsedMilliseconds / 1000f;
            float rate    = totalRayCount / seconds;
            float mRate   = rate / 1_000_000;

            Console.WriteLine($"totalRayCount: {totalRayCount}");
            Console.WriteLine($"BVH max depth: {worldBVH.MaxTestCount}");
            Console.WriteLine($"Duration: {seconds} | Rate: {mRate} MRays / sec.");
        }
예제 #4
0
파일: game.cs 프로젝트: tincann/AGR
        public void Init(OpenTKApp app, CancellationToken exitToken)
        {
            _exitToken = exitToken;
            _app       = app;
            _tasks     = new Task[parallelBundles];
            _r         = RNG.CreateMultipleRNGs(parallelBundles);

            Screen.Clear(0x2222ff);
            _acc = new Accumulator(Screen);

            //var tracer = new WhittedStyleTracer();
            var tracer = new PathTracer();

            _scene        = new Scene(tracer, constructBVH: true);
            _sceneManager = new SceneManager(_camera, _scene);

            _sceneManager.Add(SceneDefinitions.Default);
            _sceneManager.Add(SceneDefinitions.DarkRoom);
            _sceneManager.Add(SceneDefinitions.PathTracerBoxCool);
            _sceneManager.Add(SceneDefinitions.PathTracerBox);
            _sceneManager.Add(SceneDefinitions.BeerTest);
            _sceneManager.Add(SceneDefinitions.Teapot);

            _sceneManager.SetScene(0);

            Statistics.Enabled = false;
        }
예제 #5
0
        public void BoxTest()
        {
            var box0 = new Vec(0, 0, 0);
            var box1 = new Vec(10, 20, 30);

            Assert.IsTrue(equalF(PathTracer.probeBox(new Vec(5, 5, 5), box0, box1), -5.0), "Inside box");
            Assert.IsTrue(equalF(PathTracer.probeBox(new Vec(5, 25, 5), box0, box1), 5.0), "Outside the box");
        }
예제 #6
0
        public void CylTest()
        {
            var cyl0 = new Vec(-10, 6, 12);

            Assert.IsTrue(equalF(PathTracer.probeCylinder(new Vec(-10, 6, 13), cyl0, 3, 3), -1.0), "Inside cyl");
            Assert.IsTrue(equalF(PathTracer.probeCylinder(new Vec(-10, 6, 11), cyl0, 3, 3), 1.0), "Outside cyl");
            Assert.IsTrue(equalF(PathTracer.probeCylinder(new Vec(-10, 7, 17), cyl0, 3, 10), -2.0), "Inside cyl radial");
            Assert.IsTrue(equalF(PathTracer.probeCylinder(new Vec(-10, 10, 17), cyl0, 3, 10), 1.0), "Outside cyl radial");
        }
예제 #7
0
    private void OnGUI()
    {
        if (GUILayout.Button("Start Render"))
        {
            PathTracer p = SceneView.lastActiveSceneView.camera.gameObject.GetComponent <PathTracer>();
            if (p == null)
            {
                p = SceneView.lastActiveSceneView.camera.gameObject.AddComponent <PathTracer>();
                p.Setup(SceneView.lastActiveSceneView.camera);
            }
        }

        if (GUILayout.Button("Stop Render"))
        {
            PathTracer p = SceneView.lastActiveSceneView.camera.gameObject.GetComponent <PathTracer>();
            if (p != null)
            {
                p.Dispose();
                Object.DestroyImmediate(p);
            }
        }

        EditorGUILayout.Space();

        if (GUILayout.Button("Debug Uniform Grid"))
        {
            GameObject existing_grid = GameObject.Find("debug_grid");
            if (existing_grid != null)
            {
                Object.DestroyImmediate(existing_grid.gameObject);
            }

            AccelerationStructures.BuildUniformGridGPU();

            GameObject grid = GameObject.CreatePrimitive(PrimitiveType.Cube);
            grid.name = "debug_grid";
            grid.transform.position   = AccelerationStructures.SceneBounds.center;
            grid.transform.localScale = AccelerationStructures.SceneBounds.size;

            Material grid_material = new Material(Shader.Find("PathTracing/UniformGridDebug"));

            grid_material.SetBuffer("grid_data", AccelerationStructures.GridData);

            grid_material.SetVector("grid_origin", AccelerationStructures.GridInfo.grid_origin);
            grid_material.SetVector("grid_size", AccelerationStructures.GridInfo.grid_size);
            grid_material.SetInt("num_cells_x", (int)AccelerationStructures.GridInfo.nx);
            grid_material.SetInt("num_cells_y", (int)AccelerationStructures.GridInfo.ny);
            grid_material.SetInt("num_cells_z", (int)AccelerationStructures.GridInfo.nz);
            grid.GetComponent <MeshRenderer>().material = grid_material;
        }
    }
예제 #8
0
        private void TracePolygons(IPolygon[] polygons)
        {
            tracer = new PathTracer(polygons, goal, excludedPolygons);
            do
            {
                var intersection = FindNearestPolygonIntersection(polygons);
                if (intersection == null)
                {
                    return;
                }

                currentPoint = intersection.Intersection;
                currentPath.Add(currentPoint);
                currentPoint = tracer.Trace(currentPoint, currentPath, intersection.Polygon);
                currentPath.Add(currentPoint);
            } while (true);
        }
예제 #9
0
        public static void Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            TraceWriter log)
        {
            string name = req.Query["name"];
            int    nx   = 300;
            int    ny   = 300;
            int    ns   = 50;

            string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath;

            path  = Path.GetFullPath(path);
            path  = Path.GetDirectoryName(path);
            path += @"\..\teapot.obj";

            log.Info($"Obj path: {path}");

            var(world, cam) = Scenes.CornellScene(path, new SunsetquestRandom(), nx, ny);

            var worldBVH = new BVH(world);
            var wl       = new IHitable[] { worldBVH };

            var  pathTracer    = new PathTracer(nx, ny, ns, false);
            uint totalRayCount = 0;
            var  sw            = Stopwatch.StartNew();
            var  image         = pathTracer.RenderScene(wl, cam, ref totalRayCount, (pcComplete => log.Info($"{pcComplete}%")));

            sw.Stop();
            //image.Save("test.png");
            float seconds = sw.ElapsedMilliseconds / 1000f;
            float rate    = totalRayCount / seconds;
            float mRate   = rate / 1_000_000;

            log.Info($"totalRayCount: {totalRayCount}");
            log.Info($"BVH max depth: {worldBVH.MaxTestCount}");
            log.Info($"Duration: {seconds} | Rate: {mRate} MRays / sec.");

            log.Info($"C# Queue trigger function processed: ");
        }
예제 #10
0
        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
예제 #11
0
        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