Пример #1
0
        private Vector3 CastPrimaryRay(Ray ray, Scene scene, int depth = 0)
        {
            foreach (Primitive p in scene.primitives)
            {
                p.Intersect(ray);
            }
            //Nu alleen nog de kleur van het object, geen shadow rays e.d.
            if (ray.objectHit == null) //If no object has been hit load the skybox.
            {
                return Vector3.Zero;
            }

            if (ray.D.Y < .01f && ray.D.Y > -.01f)
            {
                if (depth != 0)
                    Debug.Rays.Add(ray);
            }

            Vector3 intersection = ray.GetPoint();
            Vector3 color = ray.objectHit.GetTexture(intersection);

            if (ray.objectHit.specular && depth < 20)
            {
                //Object is een spiegel, cast een tweede primary ray
                Vector3 N = ray.objectHit.GetNormal(ray.GetPoint());
                Vector3 R = ray.D - 2 * (Vector3.Dot(ray.D, N) * N);
                Ray secondaryRay = new Ray(intersection, R, float.MaxValue);
                return color * CastPrimaryRay(secondaryRay, scene, depth + 1);
            }
            //Object weerkaatst licht diffuus, cast shadowrays naar lampen OF max depth is gehaald en meer primary rays tekenen wordt te duur
            return color * CastShadowRay(intersection, ray.objectHit, scene);
        }
Пример #2
0
 // initialize renderer: takes in command line parameters passed by template code
 public void Init(int rt, bool gpu, int platformIdx)
 {
     // pass command line parameters
     runningTime = rt;
     useGPU = gpu;
     gpuPlatform = platformIdx;
     // initialize accumulator
     accumulator = new Vector3[screen.width * screen.height];
     ClearAccumulator();
     // setup scene
     scene = new Scene();
     // setup camera
     camera = new Camera(screen.width, screen.height);
     schermVerdeling = new Vector4[schermDeler * schermDeler];
     int index = 0;
     widthd = screen.width / schermDeler;
     heightd = screen.height / schermDeler;
     for (int x = 0; x < schermDeler; x++)
     {
         for (int y = 0; y < schermDeler; y++)
         {
             schermVerdeling[index] = new Vector4(x * screen.width / schermDeler, (x + 1) * screen.width / schermDeler, y * screen.height / schermDeler, (y + 1) * screen.height / schermDeler);
             index++;
         }
     }
     InitGPU(platformIdx);
 }
Пример #3
0
        // initialize
        public void Init(Rectangle bounds)
        {
            screen = new Surface(bounds.Width, bounds.Height);
            camera = new Camera(bounds.Width, bounds.Height);
            scene = new Scene();

            Application.CreateApplication(camera, screen, scene, bounds);
            Debug.CreateDebug(scene, screen);
        }
Пример #4
0
        // initialize renderer: takes in command line parameters passed by template code
        public void Init(int rt, bool gpu, int platformIdx)
        {
            // pass command line parameters
            runningTime = rt;
            useGPU = gpu;
            gpuPlatform = platformIdx;
            // initialize accumulator
            accumulator = new Vector3[screen.width * screen.height];
            ClearAccumulator();
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera(screen.width, screen.height);
            rngQueue = new ConcurrentQueue<Random>();

            xtiles = (int)Math.Ceiling((float)screen.width / TILESIZE);
            ytiles = (int)Math.Ceiling((float)screen.height / TILESIZE);

#if DEBUG
            RTTools.factorials[0] = Vector<float>.One;
            for (int i = 1; i < RTTools.TERMS * 2; i++)
                RTTools.factorials[i] = RTTools.factorials[i - 1] * i;
            //for (int i = 0; i < RTTools.TERMS; i++)
            //    RTTools.atanStuff[i] = (new Vector<float>((float)Math.Pow(2, 2 * i)) * (RTTools.factorials[i] * RTTools.factorials[i])) / RTTools.factorials[2 * i + 1];
#endif

#region OpenCL related things

            randNums = new float[screen.width * screen.height + 25];

            var streamReader = new StreamReader("../../assets/GPUCode.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            platform = ComputePlatform.Platforms[gpuPlatform];
            context = new ComputeContext(ComputeDeviceTypes.Gpu,
                new ComputeContextPropertyList(platform), null, IntPtr.Zero);

            program = new ComputeProgram(context, clSource);
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
                kernel = program.CreateKernel("Test");
            }
            catch
            {
                Console.Write("error in kernel code:\n");
                Console.Write(program.GetBuildLog(context.Devices[0]) + "\n");
                Debugger.Break();
            }

            eventList = new ComputeEventList();
            commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
#endregion
        }
Пример #5
0
        public void Render(Camera cam, Surface screen, Scene scene)
        {
            Parallel.For(0, screen.height, y =>
            {
                float hi = y / (float)screen.height;

                for (int x = 0; x < (screen.width / 2); x++)
                {
                    float wi = x / ((float)screen.width / 2);

                    RenderPixel(cam, screen, scene, hi, wi, x, y);
                }
            });
        }
Пример #6
0
 // initialize renderer: takes in command line parameters passed by template code
 public void Init( int rt, bool gpu, int platformIdx )
 {
     // pass command line parameters
     runningTime = rt;
     useGPU = gpu;
     gpuPlatform = platformIdx;
     // initialize accumulator
     accumulator = new Vector3[ screen.width * screen.height ];
     ClearAccumulator();
     // setup scene
     scene = new Scene();
     // setup camera
     camera = new Camera( screen.width, screen.height );
 }
Пример #7
0
        //Constructor of the application.
        static public void CreateApplication(Camera cam, Surface scr, Scene sce, Rectangle bound)
        {
            raytracer = new Raytracer();
            camera = cam;
            screen = scr;
            scene = sce;
            bounds = bound;

            //Move the cursor to the middle of the screen and instantiate the variables to measure mouse movement.
            Cursor.Position = new Point(bounds.Left + bounds.Width / 2, bounds.Top + bounds.Height / 2);
            currentCursor = Cursor.Position;
            previousCursor = Cursor.Position;

            mouseDelta = Vector2.Zero;
        }
Пример #8
0
        public void RenderPixel(Camera cam, Surface screen, Scene scene, float hi, float wi, int x, int y)
        {
            Vector3[] points = cam.GetPoints;
            Vector3 direction = new Vector3();
            Vector3 result;
            Ray ray;

            if (AntiAlias)
            {

                float offX = 1 / 2f * 1 / screen.width;
                float offY = 1 / 2f * 1 / screen.height;

                Vector3 directionLB = points[0] + wi * (points[1] - points[0]) + hi * (points[2] - points[0]);
                Vector3 directionRB = points[0] + (wi + offX) * (points[1] - points[0]) + hi * (points[2] - points[0]);
                Vector3 directionLO = points[0] + wi * (points[1] - points[0]) + (hi + offY) * (points[2] - points[0]);
                Vector3 directionRO = points[0] + (wi + offX) * (points[1] - points[0]) +
                                      (hi + offY) * (points[2] - points[0]);

                ray = new Ray(cam.Position, directionLB, float.MaxValue);
                Ray ray2 = new Ray(cam.Position, directionRB, float.MaxValue);
                Ray ray3 = new Ray(cam.Position, directionLO, float.MaxValue);
                Ray ray4 = new Ray(cam.Position, directionRO, float.MaxValue);

                Vector3 res1 = CastPrimaryRay(ray, scene);
                Vector3 res2 = CastPrimaryRay(ray2, scene);
                Vector3 res3 = CastPrimaryRay(ray3, scene);
                Vector3 res4 = CastPrimaryRay(ray4, scene);

                result = (res1 + res2 + res3 + res4) / 4;
            }
            else
            {
                direction = points[0] + wi * (points[1] - points[0]) + hi * (points[2] - points[0]);

                ray = new Ray(cam.Position, direction, float.MaxValue);
                result = CastPrimaryRay(ray, scene);
            }

            if (ray.D.Y < .01f && ray.D.Y > -.01f && x % 10 == 0)
            {
                Debug.Rays.Add(ray);
            }

            //screen.pixels[x + y * screen.width] = VectorToColor(CastPrimaryRay(ray, screen, scene, 0));
            screen.pixels[x + y * screen.width] = VectorToColor(result);
        }
Пример #9
0
        bool useGPU = true; // GPU code enabled (from commandline)

        #endregion Fields

        #region Methods

        // initialize renderer: takes in command line parameters passed by template code
        public void Init( int rt, bool gpu, int platformIdx )
        {
            // pass command line parameters
            runningTime = rt;
            useGPU = gpu;
            gpuPlatform = platformIdx;
            // initialize accumulator
            accumulator = new Vector3[screen.width * screen.height];
            ClearAccumulator();
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera( screen.width, screen.height );

            // Generate randoms
            Console.Write("Generating randoms....\t");

            randoms = new float[1000];
            Random r = RTTools.GetRNG();
            for (int i = 0; i < 1000; i++)
            randoms[i] = (float)r.NextDouble();

            int variable = r.Next();

            Console.WriteLine("Done!");

            // initialize required opencl things if gpu is used
            if (useGPU)
            {
            StreamReader streamReader = new StreamReader("../../kernel.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            platform = ComputePlatform.Platforms[0];
            context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);
            queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

            program = new ComputeProgram(context, clSource);
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
                kernel = program.CreateKernel("Main");

                sceneBuffer = new ComputeBuffer<Vector4>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.toCL());
                rndBuffer = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms);
                cameraBuffer = new ComputeBuffer<Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL());
                outputBuffer = new ComputeBuffer<int>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer, screen.pixels);
                skydome = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.Skydome);

                kernel.SetMemoryArgument(0, outputBuffer);
                kernel.SetValueArgument(1, screen.width);
                kernel.SetValueArgument(2, screen.height);
                kernel.SetMemoryArgument(3, sceneBuffer);
                kernel.SetValueArgument(4, scene.toCL().Length);
                kernel.SetMemoryArgument(5, skydome);
                kernel.SetMemoryArgument(6, cameraBuffer);
                kernel.SetMemoryArgument(7, rndBuffer);

            }
            catch (ComputeException e) {
                Console.WriteLine("Error in kernel code: {0}", program.GetBuildLog(context.Devices[0]));
                Console.ReadLine();
                useGPU = false;
            }
            }
            else {
            return;
            }
        }
Пример #10
0
        private Vector3 CastShadowRay(Vector3 intersection, Primitive prim, Scene scene)
        {
            Vector3 light = new Vector3(0, 0, 0);
            foreach (Light l in scene.lights)
            {
                //Richting van de ray is van lamp naar object
                Vector3 toLight = intersection - l.pos;
                float tmax = toLight.Length - 2 * Epsilon;
                Ray shadowRay = new Ray(l.pos - toLight * Epsilon, toLight, float.MaxValue);

                //Negatief, omdat de shadowray van lamp naar object gaat ipv andersom
                Vector3 N = -1f * prim.GetNormal(intersection);
                float incidence = Vector3.Dot(N, shadowRay.D);

                if (incidence > 0)
                {
                    foreach (Primitive p in scene.primitives)
                    {
                        p.Intersect(shadowRay);
                        //Als de ray iets raakt tussen de lamp en het object, abort mission
                        if (shadowRay.l < tmax)
                        {
                            break;
                        }
                    }
                    //Check of er geen objecten tussen de lamp en het object zitten
                    if (shadowRay.l >= tmax)
                    {
                        light += (l.color * (1 / (shadowRay.l * shadowRay.l))) * incidence;
                    }
                }
            }

            foreach (Spotlight spot in scene.spots)
            {
                //Richting van de ray is van lamp naar object
                Vector3 toLight = intersection - spot.pos;
                float tmax = toLight.Length - 2 * Epsilon;
                Ray shadowRay = new Ray(spot.pos - toLight * Epsilon, toLight, float.MaxValue);

                //Negatief, omdat de shadowray van lamp naar object gaat ipv andersom
                Vector3 N = -1f * prim.GetNormal(intersection);
                float incidence = Vector3.Dot(N, shadowRay.D);
                float incidenceOnSpot = Vector3.Dot(shadowRay.D, spot.D);

                if (incidence > 0 && incidenceOnSpot > spot.minDot)
                {
                    foreach (Primitive p in scene.primitives)
                    {
                        p.Intersect(shadowRay);
                        //Als de ray iets raakt tussen de lamp en het object, abort mission
                        if (shadowRay.l < tmax)
                        {
                            break;
                        }
                    }
                    //Check of er geen objecten tussen de lamp en het object zitten
                    if (shadowRay.l >= tmax)
                    {
                        light += (spot.color * (1 / (shadowRay.l * shadowRay.l))) * incidence;
                    }
                }
            }

            return light;
        }
Пример #11
0
        // initialize renderer: takes in command line parameters passed by template code
        public void Init(int rt, bool gpu, int platformIdx)
        {
            // pass command line parameters
            runningTime = rt;
            useGPU = gpu;
            gpuPlatform = platformIdx;
            //Determine tile width and height
            tileCount = GreatestDiv(screen.width, screen.height);
            tileWidth = screen.width/tileCount;
            tileHeight = screen.height/tileCount;
            // initialize accumulator
            accumulator = new Vector3[screen.width * screen.height];
            ClearAccumulator();
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera(screen.width, screen.height);

            //Init OpenCL
            ComputePlatform platform = ComputePlatform.Platforms[gpuPlatform];
            context = new ComputeContext(
                ComputeDeviceTypes.Gpu,
                new ComputeContextPropertyList(platform),
                null,
                IntPtr.Zero
                );
            var streamReader = new StreamReader("../../program.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            ComputeProgram program = new ComputeProgram(context, clSource);

            //try to compile
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
            }
            catch
            {
                Console.Write("error in kernel code:\n");
                Console.Write(program.GetBuildLog(context.Devices[0]) + "\n");
            }
            kernel = program.CreateKernel("device_function");

            //setup RNG
            rngSeed = new int[screen.width * screen.height];
            Random r = RTTools.GetRNG();
            for (int i = 0; i < rngSeed.Length; i++)
                rngSeed[i] = r.Next();

            //import buffers etc to GPU
            Vector3[] data = new Vector3[screen.width * screen.height];
            Vector3[] sphereOrigins = Scene.GetOrigins;
            float[] sphereRadii = Scene.GetRadii;

            var FlagRW = ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer;
            var FlagR = ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer;

            rngBuffer = new ComputeBuffer<int>(context, FlagRW, rngSeed);
            screenPixels = new ComputeBuffer<int>(context, FlagRW, screen.pixels);
            skyBox = new ComputeBuffer<float>(context, FlagR, scene.skybox);
            originBuffer = new ComputeBuffer<Vector3>(context, FlagR, sphereOrigins);
            radiusBuffer = new ComputeBuffer<float>(context, FlagR, sphereRadii);
            accBuffer = new ComputeBuffer<Vector3>(context, FlagRW, accumulator);

            kernel.SetValueArgument(0, camera.p1);
            kernel.SetValueArgument(1, camera.p2);
            kernel.SetValueArgument(2, camera.p3);
            kernel.SetValueArgument(3, camera.up);
            kernel.SetValueArgument(4, camera.right);
            kernel.SetValueArgument(5, camera.pos);
            kernel.SetValueArgument(6, camera.lensSize);
            kernel.SetValueArgument(7, (float)screen.width);
            kernel.SetValueArgument(8, (float)screen.height);
            kernel.SetMemoryArgument(9, rngBuffer);
            kernel.SetMemoryArgument(10, screenPixels);
            kernel.SetMemoryArgument(11, skyBox);
            kernel.SetMemoryArgument(12, originBuffer);
            kernel.SetMemoryArgument(13, radiusBuffer);
            kernel.SetMemoryArgument(14, accBuffer);

            queue = new ComputeCommandQueue(context, context.Devices[0], 0);

            long[] tempWorkSize = { screen.width * screen.height };             //For some reason, doing this directly produces a build error.
            workSize = tempWorkSize;                                            //Luckily, this works.
        }
Пример #12
0
 //Constructor.
 public static void CreateDebug(Scene sce, Surface scr)
 {
     Rays = new List<Ray>();
     scene = sce;
     screen = scr;
 }