Exemple #1
0
 /// <summary>
 /// Creates a new empty geometry.
 /// </summary>
 public Geometry(SceneFlags sceneFlags, TraversalFlags traversalFlags = TraversalFlags.Single)
 {
     RTC.Register();
     this.sceneFlags     = sceneFlags;
     this.traversalFlags = traversalFlags;
     scenePtr            = RTC.NewScene(sceneFlags, traversalFlags);
 }
Exemple #2
0
 /// <summary>
 /// Creates a new empty geometry.
 /// </summary>
 public Geometry(Device device, SceneFlags sceneFlags, TraversalFlags traversalFlags = TraversalFlags.Single)
 {
     this.device         = device;
     this.sceneFlags     = sceneFlags;
     this.traversalFlags = traversalFlags;
     scenePtr            = RTC.NewScene(device.DevicePtr, sceneFlags, traversalFlags);
 }
Exemple #3
0
        private static void CreateGeometry(Device device, SceneFlags sceneFlags, TraversalFlags traversalFlags, MeshFlags meshFlags, TriangleMesh sphere, int numMeshes)
        {
            using (var scene = new Scene <Sphere>(device, sceneFlags, traversalFlags))
            {
                for (var t = 0; t < numMeshes; ++t)
                {
                    scene.Add(new Sphere(device, sceneFlags, traversalFlags, sphere, meshFlags));

                    for (int v = 0; v < sphere.Vertices.Count; ++v)
                    {
                        sphere.Vertices[v] = (Vector)sphere.Vertices[v] + new Vector(1, 1, 1);
                    }
                }

                scene.Commit();
            }
        }
Exemple #4
0
        /// <summary>
        /// Parses command-line arguments for traversal flags.
        /// </summary>
        private static TraversalFlags ParseCommandLineArguments(String[] args)
        {
            TraversalFlags flags = 0;

            foreach (var arg in args)
            {
                int v;
                if (int.TryParse(arg, out v))
                {
                    switch (v)
                    {
                    case 1:
                        flags |= TraversalFlags.Single;
                        break;

                    case 4:
                        flags |= TraversalFlags.Packet4;
                        break;

                    case 8:
                        flags |= TraversalFlags.Packet8;
                        break;

                    case 16:
                        flags |= TraversalFlags.Packet16;
                        break;

                    default:
                        throw new ArgumentException("Unknown ray packet size argument");
                    }
                }
                else if (!arg.Equals("verbose"))
                {
                    throw new ArgumentException("Failed to parse ray packet size argument");
                }
            }
            if (flags == 0) // If no arguments, fall back to 1/8
            {
                flags = TraversalFlags.Single | TraversalFlags.Packet4 | TraversalFlags.Packet8;
            }
            return(flags);
        }
Exemple #5
0
        /// <summary>
        /// Parses command-line arguments for traversal flags.
        /// </summary>
        private static void ParseCommandLineArguments(String[] args)
        {
            if (args.Length == 0) // If no arguments, fall back to 1/4
            {
                Flags = TraversalFlags.Single | TraversalFlags.Packet4;
            }
            else
            {
                foreach (var arg in args)
                {
                    try
                    {
                        switch (int.Parse(arg))
                        {
                        case 1:
                            Flags |= TraversalFlags.Single;
                            break;

                        case 4:
                            Flags |= TraversalFlags.Packet4;
                            break;

                        case 8:
                            Flags |= TraversalFlags.Packet8;
                            break;

                        case 16:
                            Flags |= TraversalFlags.Packet16;
                            break;

                        default:
                            throw new ArgumentException("Unknown ray packet size argument");
                        }
                    }
                    catch (FormatException)
                    {
                        throw new ArgumentException("Failed to parse ray packet size argument");
                    }
                }
            }
        }
Exemple #6
0
 /// <summary>
 /// Parses command-line arguments for traversal flags.
 /// </summary>
 private static void ParseCommandLineArguments(String[] args)
 {
     if (args.Length == 0) // If no arguments, fall back to 1/4
         Flags = TraversalFlags.Single | TraversalFlags.Packet4;
     else
     {
         foreach (var arg in args)
         {
             try
             {
                 switch (int.Parse(arg))
                 {
                     case 1:
                         Flags |= TraversalFlags.Single;
                         break;
                     case 4:
                         Flags |= TraversalFlags.Packet4;
                         break;
                     case 8:
                         Flags |= TraversalFlags.Packet8;
                         break;
                     case 16:
                         Flags |= TraversalFlags.Packet16;
                         break;
                     default:
                         throw new ArgumentException("Unknown ray packet size argument");
                 }
             }
             catch (FormatException)
             {
                 throw new ArgumentException("Failed to parse ray packet size argument");
             }
         }
     }
 }
Exemple #7
0
 public Sphere(SceneFlags sceneFlags, TraversalFlags traversalFlags, IMesh mesh, MeshFlags meshFlags = MeshFlags.Static)
 {
     geometry = new Geometry(sceneFlags, traversalFlags);
     geometry.Add(mesh, meshFlags);
 }
Exemple #8
0
 public Sphere(SceneFlags sceneFlags, TraversalFlags traversalFlags, int numPhi, MeshFlags meshFlags = MeshFlags.Static)
 {
     geometry = new Geometry(sceneFlags, traversalFlags);
     geometry.Add(GenerateSphere(numPhi), meshFlags);
 }
Exemple #9
0
 public static extern IntPtr NewScene(SceneFlags flags, TraversalFlags aFlags);
Exemple #10
0
 public Sphere(SceneFlags sceneFlags, TraversalFlags traversalFlags, IMesh mesh, MeshFlags meshFlags = MeshFlags.Static)
 {
     geometry = new Geometry(sceneFlags, traversalFlags);
     geometry.Add(mesh, meshFlags);
 }
Exemple #11
0
 public Sphere(SceneFlags sceneFlags, TraversalFlags traversalFlags, int numPhi, MeshFlags meshFlags = MeshFlags.Static)
 {
     geometry = new Geometry(sceneFlags, traversalFlags);
     geometry.Add(GenerateSphere(numPhi), meshFlags);
 }
Exemple #12
0
        public static IEnumerable<Tuple<String, Action, Func<Double, String>>> Geometries(SceneFlags sceneFlags, TraversalFlags traversalFlags)
        {
            var items = new Dictionary<String, Tuple<int, int>>
            {
                { "120", new Tuple<int, int>(6, 1) },
                { "1k", new Tuple<int, int>(17, 1) },
                { "10k", new Tuple<int, int>(51, 1) },
                { "100k", new Tuple<int, int>(159, 1) },
                { "1000k_1", new Tuple<int, int>(501, 1) },
                { "100k_10", new Tuple<int, int>(159, 10) },
                { "10k_100", new Tuple<int, int>(51, 100) },
                { "1k_1000", new Tuple<int, int>(17, 1000) },
                //{ "120_10000", new Tuple<int, int>(6, 8334) },
            };

            foreach (var item in items)
            {
                var sphere = (TriangleMesh)Sphere.GenerateSphere(item.Value.Item1);
                yield return new Tuple<String, Action, Func<Double, String>>("create_static_geometry_" + item.Key,
                                                                             () => CreateGeometry(sceneFlags, traversalFlags, MeshFlags.Static, sphere, item.Value.Item2),
                                                                             (t) => String.Format("{0:N3} Mtris/s", 1e-6 * item.Value.Item2 * sphere.Indices.Count / 3));
            }

            foreach (var item in items)
            {
                var sphere = (TriangleMesh)Sphere.GenerateSphere(item.Value.Item1);
                yield return new Tuple<String, Action, Func<Double, String>>("create_dynamic_geometry_" + item.Key,
                                                                             () => CreateGeometry(sceneFlags, traversalFlags, MeshFlags.Dynamic, sphere, item.Value.Item2),
                                                                             (t) => String.Format("{0:N3} Mtris/s", 1e-6 * item.Value.Item2 * sphere.Indices.Count / 3));
            }
        }
Exemple #13
0
        public static IEnumerable<Tuple<String, Action, Func<Double, String>>> Occlusions(SceneFlags sceneFlags, TraversalFlags traversalFlags, int numPhi, int w, int h)
        {
            Func<Double, String> timer = (t) => String.Format("{0:N3} Mrays/s", 1e-6 * w * h / t);

            using (var scene = new Scene<Sphere>(sceneFlags, traversalFlags))
            {
                scene.Add(new Sphere(sceneFlags, traversalFlags, numPhi));
                scene.Commit();

                if (traversalFlags.HasFlag(TraversalFlags.Single))
                    yield return new Tuple<String, Action, Func<Double, String>>("coherent_occlusion1",
                                                                                 () => CoherentOcclusion1(scene, w, h),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet4))
                    yield return new Tuple<String, Action, Func<Double, String>>("coherent_occlusion4",
                                                                                 () => CoherentOcclusion4(scene, w, h),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet8))
                    yield return new Tuple<String, Action, Func<Double, String>>("coherent_occlusion8",
                                                                                 () => CoherentOcclusion8(scene, w, h),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet16))
                    yield return new Tuple<String, Action, Func<Double, String>>("coherent_occlusion16",
                                                                                 () => CoherentOcclusion16(scene, w, h),
                                                                                 timer);

                var random = new Random();
                var rays = new Ray[w * h];

                for (var t = 0; t < w * h; ++t)
                    rays[t] = new Ray(Vector.Zero, new Vector(2 * (float)random.NextDouble() - 1,
                                                              2 * (float)random.NextDouble() - 1,
                                                              2 * (float)random.NextDouble() - 1));

                if (traversalFlags.HasFlag(TraversalFlags.Single))
                    yield return new Tuple<String, Action, Func<Double, String>>("incoherent_occlusion1",
                                                                                 () => IncoherentOcclusion1(scene, w * h, rays),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet4))
                    yield return new Tuple<String, Action, Func<Double, String>>("incoherent_occlusion4",
                                                                                 () => IncoherentOcclusion4(scene, w * h, rays),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet8))
                    yield return new Tuple<String, Action, Func<Double, String>>("incoherent_occlusion8",
                                                                                 () => IncoherentOcclusion8(scene, w * h, rays),
                                                                                 timer);
                if (traversalFlags.HasFlag(TraversalFlags.Packet16))
                    yield return new Tuple<String, Action, Func<Double, String>>("incoherent_occlusion16",
                                                                                 () => IncoherentOcclusion16(scene, w * h, rays),
                                                                                 timer);
            }
        }
Exemple #14
0
        private static void CreateGeometry(SceneFlags sceneFlags, TraversalFlags traversalFlags, MeshFlags meshFlags, TriangleMesh sphere, int numMeshes)
        {
            using (var scene = new Scene<Sphere>(sceneFlags, traversalFlags))
            {
                for (var t = 0; t < numMeshes; ++t)
                {
                    scene.Add(new Sphere(sceneFlags, traversalFlags, sphere, meshFlags));

                    for (int v = 0; v < sphere.Vertices.Count; ++v)
                        sphere.Vertices[v] = (Vector)sphere.Vertices[v] + new Vector(1, 1, 1);
                }

                scene.Commit();
            }
        }
Exemple #15
0
        public static IEnumerable <Tuple <String, Action, Func <Double, String> > > Occlusions(Device device, SceneFlags sceneFlags, TraversalFlags traversalFlags, int numPhi, int w, int h)
        {
            Func <Double, String> timer = (t) => String.Format("{0:N3} Mrays/s", 1e-6 * w * h / t);

            using (var scene = new Scene <Sphere>(device, sceneFlags, traversalFlags))
            {
                scene.Add(new Sphere(scene.Device, sceneFlags, traversalFlags, numPhi));
                scene.Commit();

                if (traversalFlags.HasFlag(TraversalFlags.Single))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("coherent_occlusion1",
                                                                                    () => CoherentOcclusion1(scene, w, h),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet4))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("coherent_occlusion4",
                                                                                    () => CoherentOcclusion4(scene, w, h),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet8))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("coherent_occlusion8",
                                                                                    () => CoherentOcclusion8(scene, w, h),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet16))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("coherent_occlusion16",
                                                                                    () => CoherentOcclusion16(scene, w, h),
                                                                                    timer));
                }

                var random = new Random();
                var rays   = new Ray[w * h];

                for (var t = 0; t < w * h; ++t)
                {
                    rays[t] = new Ray(Vector.Zero, new Vector(2 * (float)random.NextDouble() - 1,
                                                              2 * (float)random.NextDouble() - 1,
                                                              2 * (float)random.NextDouble() - 1));
                }

                if (traversalFlags.HasFlag(TraversalFlags.Single))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("incoherent_occlusion1",
                                                                                    () => IncoherentOcclusion1(scene, w * h, rays),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet4))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("incoherent_occlusion4",
                                                                                    () => IncoherentOcclusion4(scene, w * h, rays),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet8))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("incoherent_occlusion8",
                                                                                    () => IncoherentOcclusion8(scene, w * h, rays),
                                                                                    timer));
                }
                if (traversalFlags.HasFlag(TraversalFlags.Packet16))
                {
                    yield return(new Tuple <String, Action, Func <Double, String> >("incoherent_occlusion16",
                                                                                    () => IncoherentOcclusion16(scene, w * h, rays),
                                                                                    timer));
                }
            }
        }
Exemple #16
0
        public static IEnumerable <Tuple <String, Action, Func <Double, String> > > Geometries(Device device, SceneFlags sceneFlags, TraversalFlags traversalFlags)
        {
            var items = new Dictionary <String, Tuple <int, int> >
            {
                { "120", new Tuple <int, int>(6, 1) },
                { "1k", new Tuple <int, int>(17, 1) },
                { "10k", new Tuple <int, int>(51, 1) },
                { "100k", new Tuple <int, int>(159, 1) },
                { "1000k_1", new Tuple <int, int>(501, 1) },
                { "100k_10", new Tuple <int, int>(159, 10) },
                { "10k_100", new Tuple <int, int>(51, 100) },
                { "1k_1000", new Tuple <int, int>(17, 1000) },
                //{ "120_10000", new Tuple<int, int>(6, 8334) },
            };

            foreach (var item in items)
            {
                var sphere = (TriangleMesh)Sphere.GenerateSphere(device, item.Value.Item1);
                yield return(new Tuple <String, Action, Func <Double, String> >("create_static_geometry_" + item.Key,
                                                                                () => CreateGeometry(device, sceneFlags, traversalFlags, MeshFlags.Static, sphere, item.Value.Item2),
                                                                                (t) => String.Format("{0:N3} Mtris/s", 1e-6 * item.Value.Item2 * sphere.Indices.Count / 3)));
            }

            foreach (var item in items)
            {
                var sphere = (TriangleMesh)Sphere.GenerateSphere(device, item.Value.Item1);
                yield return(new Tuple <String, Action, Func <Double, String> >("create_dynamic_geometry_" + item.Key,
                                                                                () => CreateGeometry(device, sceneFlags, traversalFlags, MeshFlags.Dynamic, sphere, item.Value.Item2),
                                                                                (t) => String.Format("{0:N3} Mtris/s", 1e-6 * item.Value.Item2 * sphere.Indices.Count / 3)));
            }
        }
Exemple #17
0
        /// <summary>
        /// Renders the scene into a pixel buffer.
        /// </summary>
        public void Render(PixelBuffer pixbuf, TraversalFlags mode = TraversalFlags.Single)
        {
            float dx = 1.0f / pixbuf.Width, dy = 1.0f / pixbuf.Height;

            camera.AspectRatio = (float)pixbuf.Width / pixbuf.Height;

            // Free parallelism, why not! Note a Parallel.For loop
            // over each row is slightly faster but less readable.
            Parallel.ForEach(pixbuf, (pixel) =>
            {
                var color = Vector.Zero;
                float u   = pixel.X * dx;
                float v   = pixel.Y * dy;

                Ray[] rays = null;
                Intersection <Model>[] hits = null;
                if (mode == TraversalFlags.Single)
                {
                    rays       = new[] { camera.Trace(2 * (u - 0.25f * dx) - 1, 2 * (v - 0.25f * dy) - 1) };
                    var packet = scene.Intersects(rays[0]);
                    hits       = new Intersection <Model>[] { packet.ToIntersection <Model>(scene) };
                }
                else if (mode == TraversalFlags.Packet4)
                {
                    rays = new[]
                    {
                        camera.Trace(2 * (u - 0.25f * dx) - 1, 2 * (v - 0.25f * dy) - 1),
                        camera.Trace(2 * (u + 0.25f * dx) - 1, 2 * (v - 0.25f * dy) - 1),
                        camera.Trace(2 * (u - 0.25f * dx) - 1, 2 * (v + 0.25f * dy) - 1),
                        camera.Trace(2 * (u + 0.25f * dx) - 1, 2 * (v + 0.25f * dy) - 1)
                    };
                    // Trace a packet of coherent AA rays
                    var packet = scene.Intersects4(rays);
                    // Convert the packet to a set of usable ray-geometry intersections
                    hits = packet.ToIntersection <Model>(scene);
                }
                else if (mode == TraversalFlags.Packet8)
                {
                    // Sampling pattern Rotated grid
                    // https://en.wikipedia.org/wiki/Supersampling#Supersampling_patterns
                    // ------------
                    // | X   X    |
                    // |   X    X |
                    // | X    X   |
                    // |    X   X |
                    // ------------
                    //https://www.desmos.com/calculator/l2ynkbsahy
                    rays = new[]
                    {
                        camera.Trace(2 * (u - 0.333f * dx) - 1, 2 * (v - 0.166f * dy) - 1),
                        camera.Trace(2 * (u - 0.166f * dx) - 1, 2 * (v - 0.333f * dy) - 1),
                        camera.Trace(2 * (u - 0.300f * dx) - 1, 2 * (v + 0.300f * dy) - 1),
                        camera.Trace(2 * (u - 0.100f * dx) - 1, 2 * (v + 0.100f * dy) - 1),
                        camera.Trace(2 * (u + 0.100f * dx) - 1, 2 * (v - 0.100f * dy) - 1),
                        camera.Trace(2 * (u + 0.300f * dx) - 1, 2 * (v - 0.300f * dy) - 1),
                        camera.Trace(2 * (u + 0.166f * dx) - 1, 2 * (v + 0.333f * dy) - 1),
                        camera.Trace(2 * (u + 0.333f * dx) - 1, 2 * (v + 0.166f * dy) - 1)
                    };
                    // Trace a packet of coherent AA rays
                    var packet = scene.Intersects8(rays);
                    // Convert the packet to a set of usable ray-geometry intersections
                    hits = packet.ToIntersection <Model>(scene);
                }
                else
                {
                    throw new Exception("Invalid mode");
                }

                for (int t = 0; t < hits.Length; ++t)
                {
                    if (hits[t].HasHit)
                    {
                        color += new Vector(0.1f, 0.1f, 0.1f);

                        var ray   = rays[t];
                        var model = hits[t].Instance;

                        // Parse the surface normal returned and then process it manually
                        var rawNormal = new Vector(hits[t].NX, hits[t].NY, hits[t].NZ);
                        var normal    = model.CorrectNormal(rawNormal); // Important!

                        // Calculate the new ray towards the light source
                        var hitPoint = ray.PointAt(hits[t].Distance);
                        var toLight  = lightPosition - hitPoint; // from A to B = B - A
                        var lightRay = new Ray(hitPoint + normal * Constants.Epsilon, toLight);

                        // Is the light source occluded? If so, no point calculating any lighting
                        if (!scene.Occludes(lightRay, 0, toLight.Length()))
                        {
                            // Compute the Lambertian cosine term (rendering equation)
                            float cosLight = Vector.Dot(normal, toLight.Normalize());

                            // Calculate the total light attenuation (inverse square law + cosine law)
                            var attenuation = lightIntensity * cosLight / Vector.Dot(toLight, toLight);

                            color += model.Material(hits[t].Mesh).BRDF(toLight.Normalize(), ray.Direction, normal) * attenuation;
                        }
                    }
                }
                // Average the per-pixel samples
                pixbuf.SetColor(pixel, color / rays.Length);
            });
        }