コード例 #1
0
        private List <(Triangle, Vector3, Vector3)> GetIntersectedTriangles(ISceneCreator sceneCreator, List <INode> octrees, Vector3 rayDirection, ref int num)
        {
            var   priorityQueue = new SimplePriorityQueue <INode, float>();
            var   triangles     = new List <(Triangle, Vector3, Vector3)>();
            float t             = 0;

            foreach (var octree in octrees)
            {
                if (IsRayIntersectBox(octree.MinBoundary, octree.MaxBoundary, sceneCreator.ParamsProvider.Camera, rayDirection, ref t))
                {
                    priorityQueue.Enqueue(octree, t);
                }

                Triangle nearestTriangle = null;
                var      nearestTriangleIntersectionPoint = new Vector3();
                var      minDistance = float.MaxValue;
                var      barycentricIntersectionPoint = new Vector3();
                var      intersectionPoint            = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
                var      barycentricIntersectionPointOfNearestTriangle = new Vector3();
                var      flag = false;
                while (priorityQueue.Count != 0)
                {
                    var node = priorityQueue.Dequeue();
                    var intersectedTriangle =
                        FindIntersectionInBox(node.Faces, rayDirection, sceneCreator.ParamsProvider.Camera, ref num, ref intersectionPoint, ref barycentricIntersectionPoint);
                    var distanceBetweenCameraAndTriangle = Distance(intersectionPoint, sceneCreator.ParamsProvider.Camera);

                    if (distanceBetweenCameraAndTriangle < minDistance)
                    {
                        minDistance     = distanceBetweenCameraAndTriangle;
                        nearestTriangle = intersectedTriangle;
                        nearestTriangleIntersectionPoint = intersectionPoint;
                        barycentricIntersectionPointOfNearestTriangle = barycentricIntersectionPoint;
                        flag = true;
                    }

                    if (node.IsLeaf())
                    {
                        if (flag)
                        {
                            triangles.Add((nearestTriangle, nearestTriangleIntersectionPoint, barycentricIntersectionPointOfNearestTriangle));
                            break;
                        }
                    }
                    else
                    {
                        foreach (var child in node.ChildNodes
                                 .Where(child => IsRayIntersectBox(child.MinBoundary, child.MaxBoundary, sceneCreator.ParamsProvider.Camera, rayDirection, ref t)))
                        {
                            priorityQueue.Enqueue(child, t);
                        }
                    }
                }
            }

            return(triangles);
        }
コード例 #2
0
        public List <List <Pixel> > Trace(ISceneCreator sceneCreator, List <INode> octrees)
        {
            var camera  = sceneCreator.ParamsProvider.Camera;
            var screenZ = sceneCreator.ParamsProvider.ScreenZ;

            var watch = System.Diagnostics.Stopwatch.StartNew();
            var num   = 0;

            var image = new List <List <Pixel> >();

            for (var i = 0; i < sceneCreator.ParamsProvider.ImageHeight; i++)
            {
                image.Add(new List <Pixel>());
                var y = sceneCreator.SetXScreenCoordinate(i);
                for (var j = 0; j < sceneCreator.ParamsProvider.ImageWidth; j++)
                {
                    var x = sceneCreator.SetYScreenCoordinate(j);

                    var pixelCenterPoint = new Vector3(x, y, screenZ);
                    var rayDirection     = Normalize(pixelCenterPoint - camera);

                    // float t = 0;
                    // var priorityQueue = new SimplePriorityQueue<INode, float>();

                    var triangles = GetIntersectedTriangles(sceneCreator, octrees, rayDirection, ref num);
                    var normal    = new Vector3();
                    var sphereIntersectionPoint = new Vector3();

                    if (IsSphereIntersect(camera, rayDirection, ref normal, ref sphereIntersectionPoint))
                    {
                        var lightRay    = Normalize(sceneCreator.ParamsProvider.LightPosition - sphereIntersectionPoint);
                        var dotProduct  = Dot(lightRay, normal);
                        var facingRatio = Math.Max(0, dotProduct);
                        image[i].Add(new Pixel((byte)(239 * facingRatio), (byte)(154 * facingRatio), (byte)(154 * facingRatio)));
                    }
                    else if (!triangles.Any())
                    {
                        image[i].Add(new Pixel(232, 234, 246));
                    }
                    else
                    {
                        //var facingRatio = 0.18f / Math.PI * 30 * 0.5 * Math.Max(0f, dotProduct);
                        var(nearestTriangle, intersectionPoint, barycentricIntersectionPoint) = GetNearestTriangle(triangles, sceneCreator.ParamsProvider.Camera);

                        // trying to draw shadows
                        var shadowRay = Normalize(intersectionPoint - sceneCreator.ParamsProvider.LightPosition);
                        var barrier   = GetIntersectedTriangles(sceneCreator, octrees, shadowRay, ref num);

                        if (!barrier.Any())
                        {
                            var temp = new Vector3(0, 0, 0);
                            if (IsSphereIntersect(intersectionPoint, shadowRay, ref temp, ref temp))
                            {
                                image[i].Add(new Pixel(0, 0, 0));
                            }
                            else
                            {
                                normal = nearestTriangle.GetNormal();
                                // normal = nearestTriangle.GetBarycentricNormal(barycentricIntersectionPoint);
                                var lightRay    = Normalize(sceneCreator.ParamsProvider.LightPosition - intersectionPoint);
                                var dotProduct  = Dot(lightRay, normal);
                                var facingRatio = Math.Max(0, dotProduct);
                                var albedo      = 0.18;

                                image[i].Add(new Pixel((byte)(159 * facingRatio), (byte)(168 * facingRatio),
                                                       (byte)(218 * facingRatio)));
                            }
                        }
                        else
                        {
                            image[i].Add(new Pixel(0, 0, 0));
                        }

                        // normal = nearestTriangle.GetNormal();
                        // // normal = nearestTriangle.GetBarycentricNormal(barycentricIntersectionPoint);
                        // var lightRay = Normalize(sceneCreator.ParamsProvider.LightPosition - intersectionPoint);
                        // var dotProduct = Dot(lightRay, normal);
                        // var facingRatio = Math.Max(0, dotProduct);
                        // var albedo = 0.18;
                        //
                        // image[i].Add(new Pixel((byte) (159 * facingRatio), (byte) (168 * facingRatio),
                        //     (byte) (218 * facingRatio)));
                    }
                }
            }

            watch.Stop();
            var time = watch.ElapsedMilliseconds / 1000;

            Console.WriteLine($"Exec time: {time} s");
            Console.WriteLine($"Num of intersection tests: {num}");

            return(image);
        }
コード例 #3
0
ファイル: Startup.cs プロジェクト: AlBersha/Image-Renderer
 public Startup(ICommandProcessor commandProcessor, ISceneCreator sceneCreator,
                IObjectFromFileProvider objectFromFileProvider,
                ITreeProvider treeProvider, ITracer tracer) =>
 (_commandProcessor, _sceneCreator, _object, _treeProvider, _tracer) = (commandProcessor, sceneCreator,