コード例 #1
0
ファイル: Scene.cs プロジェクト: tomasz-herman/RayTracing
        private List <IHittable> BvhPreprocess()
        {
            Hittables.Clear();
            var planes         = new List <IHittable>();
            var hittablesToBvh = new List <IHittable>();

            foreach (var model in Models)
            {
                if (model is Plane || model is Cylinder)
                {
                    planes.Add(model);
                }
                else
                {
                    hittablesToBvh.AddRange(((IHittable)model).Preprocess());
                }
            }

            Hittables.AddRange(planes);
            if (hittablesToBvh != null && hittablesToBvh.Count > 0)
            {
                var node = new BvhNode(hittablesToBvh, 0, hittablesToBvh.Count);
                Hittables.Add(node);
            }

            return(Hittables);
        }
コード例 #2
0
    public BvhNode(Hitable[] hitables, int start, int length, float time0, float time1)
    {
        // TODO recursive -> iteration loop
        IComparer <Hitable> comparer = null;

        switch ((int)(3.0f * Util.UnitRandFloat()))
        {
        case 0:
            comparer = Boundary.compareX;
            break;

        case 1:
            comparer = Boundary.compareY;
            break;

        case 2:
        default:
            comparer = Boundary.compareZ;
            break;
        }
        System.Array.Sort(hitables, start, length, comparer);
        var halfLength = length / 2;

        switch (length)
        {
        case 1:
            left_  = hitables[start];
            right_ = hitables[start];
            break;

        case 2:
            left_  = hitables[start];
            right_ = hitables[start + 1];
            break;

        default:
            left_  = new BvhNode(hitables, start, halfLength, time0, time1);
            right_ = new BvhNode(hitables, start + halfLength, length - halfLength, time0, time1);
            break;
        }
        var boxLeft = left_.BoundingBox(time0, time1);

        if (!boxLeft.IsValid())
        {
            Debug.Log("no bounding box detected.");
        }
        var boxRight = right_.BoundingBox(time0, time1);

        if (!boxRight.IsValid())
        {
            Debug.Log("no bounding box detected.");
        }
        boundary_ = Boundary.SurroundingBoundary(boxLeft, boxRight);
    }
コード例 #3
0
        public static Model CreateFromBvh(BvhNode node)
        {
            // add nodes
            var model = new Model(Coordinates.Vrm1);

            model.Root.Name = "__bvh_root__";

            AddBvhNodeRecursive(model, model.Root, node);

            return(model);
        }
コード例 #4
0
        public static Model CreateFromBvh(BvhNode node)
        {
            // add nodes
            var model = new Model(Coordinates.Gltf)
            {
                Root = new Node("__bvh_root__"),
            };

            AddBvhNodeRecursive(model, model.Root, node);

            return(model);
        }
コード例 #5
0
    private Hitable[] OneWeekScene()
    {
        var center   = new Vector3(4.0f, 2.0f, 0.0f);
        var position = new Vector3(0.0f, -1000.0f, 0.0f);
        var hitables = new List <Hitable>(500);

        hitables.Add(new Sphere(position, -position.y, new Lambertian(0.5f * Vector3.one)));
        float radius     = 0.2f;
        var   dielectric = new Dielectric(1.5f);

        for (int a = -11; a < 11; ++a)
        {
            for (int b = -11; b < 11; ++b)
            {
                position.Set(a + 0.9f * Util.UnitRandFloat(), radius, b + 0.9f * Util.UnitRandFloat());
                if ((position - center).sqrMagnitude <= 0.81)
                {
                    continue;
                }
                var chooseMat = Util.UnitRandFloat();
                if (chooseMat < 0.8f)
                {
                    // hitables.Add(new Sphere(position, radius, new Lambertian(new Vector3(Util.UnitRandFloat(), Util.UnitRandFloat(), Util.UnitRandFloat()))));
                    hitables.Add(new MovingSphere(position, position + new Vector3(0.0f, 0.5f * Util.UnitRandFloat(), 0.0f), 0.0f, 1.0f, radius, new Lambertian(new Vector3(Util.UnitRandFloat(), Util.UnitRandFloat(), Util.UnitRandFloat()))));
                    continue;
                }
                if (chooseMat < 0.95f)
                {
                    hitables.Add(new Sphere(position, radius,
                                            new Metal(new Vector3(0.5f * (1.0f + Util.UnitRandFloat()), 0.5f * (1.0f + Util.UnitRandFloat()), 0.5f * (1.0f + Util.UnitRandFloat())),
                                                      0.5f * (1.0f + Util.UnitRandFloat()))));

                    continue;
                }
                hitables.Add(new Sphere(position, radius, dielectric));
            }
        }
        radius = 1.0f;
        position.Set(0.0f, 1.0f, 0.0f);
        hitables.Add(new Sphere(position, radius, dielectric));
        position.Set(-4.0f, 1.0f, 0.0f);
        hitables.Add(new Sphere(position, radius, new Lambertian(new Vector3(0.4f, 0.2f, 0.1f))));
        position.Set(4.0f, 1.0f, 0.0f);
        hitables.Add(new Sphere(position, radius, new Metal(new Vector3(0.7f, 0.6f, 0.5f), 0.0f)));
        var retval = new Hitable[1];

        retval[0] = new BvhNode(hitables.ToArray(), 0, hitables.Count, 0.0f, 1.0f);
        return(retval);
    }
コード例 #6
0
    static void BuildHierarchy(Transform parent, BvhNode node, float toMeter)
    {
        var go = new GameObject(node.Name);

        go.transform.localPosition = node.Offset.ToXReversedVector3() * toMeter;
        go.transform.SetParent(parent, false);

        //var gizmo = go.AddComponent<BoneGizmoDrawer>();
        //gizmo.Draw = true;

        foreach (var child in node.Children)
        {
            BuildHierarchy(go.transform, child, toMeter);
        }
    }
コード例 #7
0
        static void AddBvhNodeRecursive(Model model, Node parent, BvhNode node)
        {
            var newNode = new Node(node.Name)
            {
                HumanoidBone = node.Bone,
            };

            model.Nodes.Add(newNode);
            parent.Add(newNode);
            newNode.Translation = node.SkeletonLocalPosition;

            foreach (var child in node.Children)
            {
                AddBvhNodeRecursive(model, newNode, child);
            }
        }
コード例 #8
0
        static BvhNode GetNode(BvhNode root, string path)
        {
            var splitted = path.Split('/');

            var it      = splitted.Select(x => x).GetEnumerator();
            var current = root;

            if (splitted[0] == path)
            {
                return(current);
            }
            it.MoveNext();
            while (it.MoveNext())
            {
                current = current.Children.First(x => x.Name == it.Current);
            }

            return(current);
        }
コード例 #9
0
ファイル: App.cs プロジェクト: rje/ray
        public static void Main(string[] args)
        {
            var aspect = 1;
            //var generator = new RandomWorld();
            //var generator = new TwoSpheres();
            //var generator = new PerlinTest();
            //var generator = new EarthTest();
            //var generator = new SimpleLightTest();
            //var generator = new RectTest();
            //var generator = new CornellBox();
            //var generator = new CornellSmoke();
            var generator = new NextWeekScene();

            var imageWidth  = 400;
            var imageHeight = (int)(imageWidth / aspect);
            var cam         = generator.GetCamera(aspect);
            var objects     = generator.Generate();
            var world       = new BvhNode(objects, 0, objects.Count, 0, 1);

            var start           = DateTime.Now;
            var image           = new Image(imageWidth, imageHeight);
            var samplesPerPixel = 1024;
            var maxDepth        = 50;
            var linesRemaining  = imageHeight;

            //for(var y = 0; y < image.Height; y++)
            Parallel.For(0, image.Height, y =>
            {
                var lineStart = DateTime.Now;
                for (var x = 0; x < image.Width; x++)
                {
                    Vec3 pixelColor = Vec3.Zero;
                    //var sampleOffsets = Vec3.GenerateWhite2DNoise((int) Math.Sqrt(samplesPerPixel));
                    var sampleOffsets = Vec3.GenerateJittered2DNoise((int)Math.Sqrt(samplesPerPixel));
                    var sampleWeights = Vec3.GenerateConstantSampleWeights((int)Math.Sqrt(samplesPerPixel));
                    for (var i = 0; i < sampleOffsets.Count; i++)
                    {
                        var u       = (x + sampleOffsets[i].x) / (imageWidth - 1);
                        var v       = (y + sampleOffsets[i].y) / (imageHeight - 1);
                        var ray     = cam.GetRay(u, v);
                        pixelColor += ray.GetColor(world, maxDepth, cam.Background) * sampleWeights[i];
                    }

                    image.SetPixel(x, y, pixelColor.GammaCorrected());
                }

                Interlocked.Decrement(ref linesRemaining);
                var lineTime = DateTime.Now - lineStart;
                Console.WriteLine($"Lines remaining: {linesRemaining}, last line time: {lineTime}");
            });

            var end  = DateTime.Now;
            var diff = end - start;

            Console.WriteLine($"Render Time: {diff}");
            Console.WriteLine($"Num Rays: {Ray.RayCount}");
            Console.WriteLine($"Rays per second: {Ray.RayCount / diff.TotalSeconds}");

            var file = $"render-{DateTime.Now:yyyyMMdd-HH_mm_ss}.ppm";

            image.WriteToPpm(file);
        }