예제 #1
0
        public void Tick()
        {
            // start timer
            timer.Restart();
            // run the simulation, 1 step
            inBuffer.CopyToDevice();
            kernel.Execute(workSize);
            outBuffer.CopyFromDevice();


            for (int i = 0; i < pw * ph; i++)
            {
                _in[i] = 0;
            }

            // visualize current state, DRAW FUNCTION -> GPU BONUS.
            screen.Clear(0);
            for (uint y = 0; y < screen.height / scale; y++)
            {
                for (uint x = 0; x < screen.width / scale; x++)
                {
                    if (GetBit(x + xoffset, y + yoffset) == 1)
                    {
                        if (scale > 1)
                        {
                            for (uint j = 0; ((j + 1) % scale) != 0; j++)
                            {
                                for (uint i = 0; ((i + 1) % scale) != 0; i++)
                                {
                                    screen.Plot((x * scale + i), (y * scale + j), 0xffffff);
                                }
                            }
                        }
                        else
                        {
                            screen.Plot(x, y, 0xffffff);
                        }
                    }
                }
            }

            for (uint y = 0; y < ph; y++)
            {
                for (uint x = 0; x < pw * 32; x++)
                {
                    if (GetBit(x, y) == 1)
                    {
                        BitSet(x, y);
                    }
                }
            }


            string text = "Scale: " + scale + "x";

            screen.Print(text, 5, 5, 0xffffff);

            // report performance
            Console.WriteLine("generation " + generation++ + ": " + timer.ElapsedMilliseconds + "ms");
        }
예제 #2
0
 public void Debug()
 {
     for (int i = 0; i < raytracer.eindpunten.Length; i++)
     {
         screen.Line(((int)Xtrans(raytracer.cameraPosition.X)), ((int)Ytrans(raytracer.cameraPosition.Z)), ((int)Xtrans(raytracer.eindpunten[i].X)), ((int)Ytrans((raytracer.eindpunten[i].Y))), 0xff00ff);// tekent de ray van de camera naar een intersectie
         //screen.Line(((int)Xtrans(raytracer.eindpunten[i].X)), ((int)Ytrans(raytracer.eindpunten[i].Y)), ((int)Xtrans(scene.lightPositie.X)), ((int)Ytrans(scene.lightPositie.Z)),0x00ffff);// tekent de rays van een intersectie naar de lichtbron
     }
     r = scene.radius * (screen.height / 10);
     for (double i = 0.0; i < 360.0; i += 0.1)
     {
         hoek          = i * Math.PI / 180;
         xpositieDebug = (int)(Xtrans((int)scene.sphere1Positie.X) + r * Math.Cos(hoek));
         ypositieDebug = (int)(Ytrans((int)scene.sphere1Positie.Z) + r * Math.Sin(hoek));
         screen.Plot(xpositieDebug, ypositieDebug, CreateColorf(scene.kleur1.X, scene.kleur1.Y, scene.kleur1.Z));
     }
     for (double i = 0.0; i < 360.0; i += 0.1)
     {
         hoek          = i * Math.PI / 180;
         xpositieDebug = (int)(Xtrans((int)scene.sphere2Positie.X) + r * Math.Cos(hoek));
         ypositieDebug = (int)(Ytrans((int)scene.sphere2Positie.Z) + r * Math.Sin(hoek));
         screen.Plot(xpositieDebug, ypositieDebug, CreateColorf(scene.kleur2.X, scene.kleur2.Y, scene.kleur2.Z));
     }
     for (double i = 0.0; i < 360.0; i += 0.1)
     {
         hoek          = i * Math.PI / 180;
         xpositieDebug = (int)(Xtrans((int)scene.sphere3Positie.X) + r * Math.Cos(hoek));
         ypositieDebug = (int)(Ytrans((int)scene.sphere3Positie.Z) + r * Math.Sin(hoek));
         screen.Plot(xpositieDebug, ypositieDebug, CreateColorf(scene.kleur3.X, scene.kleur3.Y, scene.kleur3.Z));
     }
     screen.Plot(((int)Xtrans(raytracer.cameraPosition.X)), ((int)Ytrans(raytracer.cameraPosition.Z)), 0xffffff); // geeft de camera positie
     screen.Plot(((int)Xtrans(scene.lightPositie.X)), ((int)Ytrans(scene.lightPositie.Z)), 0x0fffff);             // geeft de licht positie
 }
예제 #3
0
        private void RenderRaycastScene()
        {
            int viewportWidth  = screen.width / 2;
            int viewportHeight = screen.height;

            Vector3 origin = camera.GetPosition();
            Vector3 direction;

            for (int x = 0; x < viewportWidth; x++)
            {
                for (int y = 0; y < viewportHeight; y++)
                {
                    direction = camera.GetRayDirection(x / (float)viewportWidth, y / (float)viewportHeight);
                    Ray       r         = new Ray(origin, direction);
                    Intersect intersect = new Intersect();
                    intersect.OriginalRay = r;

                    scene.IntersectWithScene(intersect);

                    screen.Plot(x, y, intersect.Col);
                    if (y == viewportHeight / 2 && x % 32 == 0)
                    {
                        screen.Line(TX(camera.GetPosition().X), TY(camera.GetPosition().Y),
                                    TX(intersect.OriginalRay.distance * direction.X + camera.GetPosition().X),
                                    TY(intersect.OriginalRay.distance * direction.Y + camera.GetPosition().Y), 255 << 8);
                    }
                }
            }
        }
예제 #4
0
        public void Render()
        {
            // Een tijdelijk array wordt gemaakt om de kleuren van het scherm in te stoppen.
            // Dit zorgt ervoor dat de debug niet over het scherm wordt geprint.
            Vector3[] colors = new Vector3[512 * 512];

            // De i houdt bij welke positie van de array er wordt gebruikt.
            int i = 0;

            for (int y = 0; y < 512; y++)
            {
                for (int x = 0; x < 512; x++)
                {
                    // De camera heeft de richtingen per pixel opgeslagen in een array, en maakt hier nu een ray van.
                    Ray ray = camera.SendRay(i);

                    // Elke zoveel rays op y = 256 worden getekent.
                    if (y == 256 && x % 20 == 0)
                    {
                        // De uiteindelijke kleur van de ray wordt hier opgeslagen.
                        colors[i] = Trace(ray, true, maxRecursion);
                        // De primary rays beginnen met een rood cirkelsegment van lengte 1, zoals in de opdracht vermeld wordt.
                        DrawDebugRay(new Ray(ray.O, ray.D, 1), new Vector3(255, 0, 0));
                    }
                    else
                    {
                        // Als het nit in de debug getekent moet worden wordt er false meegegeven.
                        colors[i] = Trace(ray, false, maxRecursion);
                    }
                    i++;
                }
            }
            // Vervolgens worden de camera, screen en primitives (alleen spheres) getekent.
            DrawDebug();

            // Tenslotte wordt de scene echt geplot.
            i = 0;
            for (int y = 0; y < 512; y++)
            {
                for (int x = 0; x < 512; x++)
                {
                    screen.Plot(x, y, FixColor(colors[i]));
                    i++;
                }
            }
        }
예제 #5
0
        public void Raytracing()
        {
            // prepare for generic OpenGL rendering
            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.Texture2D);
            GL.Clear(ClearBufferMask.DepthBufferBit);
            float FOV =  400;
            // creating a scene
            Scene Scene1 = new Scene();

            // Adding axis in the Debug view
            Scene1.toggleaxis(true);
            if (Scene1.Axis == true)
            {
                GL.Color4(1f, 1f, 1f, 1f);
                GL.Begin(PrimitiveType.Lines);
                GL.Vertex2(0.5f, 1); GL.Vertex2(0.5f, -1f);
                GL.Vertex2(0, 0); GL.Vertex2(1, 0);
                GL.End();
            }
            // Adding main objects to the scene
            Sphere Sphere1 = new Sphere(new Vector3(200, 0, 200), 100f, new Vector3(255,0,0), aspectratio);
            Sphere Sphere2 = new Sphere(new Vector3(-200, 0, 200), 100f, new Vector3(0, 0, 255), aspectratio);
            Sphere Sphere3 = new Sphere(new Vector3(-100, 0, 200), 100f, new Vector3(0, 255,0), aspectratio);
            Camera mainCamera = new Camera(new Vector3(0,0,-400), new Vector3(0,0,1), FOV);
            Light LightSource1 = new Light(new Vector3(0, 200, 200), 255, 255, 0);

            // adding light source(s) to the list
            Scene1.LightList.Add(LightSource1);

            //adding primitives to te primitive list 
            Scene1.PrimitivesList.Add(Sphere1);
            Scene1.PrimitivesList.Add(Sphere3);
            Scene1.PrimitivesList.Add(Sphere2);

            // draw every primitive in the list
            foreach (Sphere item in Scene1.PrimitivesList)
            {
                Scene1.DrawCircle(DebugConverter(item.Position), item.Color, item.Radius, screen);
            }

            // start raytracing
            Raytracer raytracer = new Raytracer();
            raytracer.Render(mainCamera, Scene1, screen);

            for (int renderx = 0; renderx < 512; renderx++)
            {
                for (int rendery = 0; rendery < 512; rendery++)
                {
                    int pixel = renderx + rendery * 512;
                    screen.Plot(renderx, rendery, (int)raytracer.Image[pixel]);
                }
            }
            Raytr = raytracer;
        }
예제 #6
0
        // tick: renders one frame
        public void Tick()
        {
			//clear
			screen.Clear(0);
			raytracer.rays.Clear();

			int DEFAULT_COLOR = convertColor(new Vector3(255));

			for (int i = 0; i < SCREEN_SIZE; i++)
			{
				for (int j = 0; j < SCREEN_SIZE; j++)
				{
					//Render Screen
					int location = i + j * SCREEN_SIZE * 2;               
					Vector3 Color = raytracer.Render(i / (SCREEN_SIZE * 1.0f), j / (SCREEN_SIZE * 1.0f));               
					screen.pixels[location] = convertColor(Color); 

					//Debug Screen Default
					screen.pixels[i + SCREEN_SIZE + j * SCREEN_SIZE * 2] = 0;        
				}
			}
            //Debug View
            //Draw Sphere
			foreach(Primitive primitive in raytracer.scene.primitives)
            {
                if(primitive is Sphere)
                {
                    Sphere sphere = (Sphere)primitive;
					for (int degree = 0; degree < 360; degree++)
                    {
						int coordX = (int)(CUBE_SIZE * (sphere.radius * Math.Cos(degree) + sphere.pos.X));
						int coordY = (int)(CUBE_SIZE * (sphere.radius * Math.Sin(degree) - sphere.pos.Z));
                        screen.Plot(coordX+ 768, coordY + 350, convertColor(sphere.Color));                        
                    }
                }                
            }              
			//Draw Camera point                 
			screen.Box((int)raytracer.camera.pos.X + 767, (int)raytracer.camera.pos.Z * -1 + 349, (int)raytracer.camera.pos.X + 769, (int)raytracer.camera.pos.Z * -1 + 351, DEFAULT_COLOR);

            //Draw Rays
			foreach(Ray ray in raytracer.rays)
			{
				float coordX = CUBE_SIZE * (ray.O.X + 40 * ray.D.X);
				float coordY = CUBE_SIZE * (ray.O.Z + 40 * ray.D.Z);            
				screen.Line((int)ray.O.X + 768, (int)ray.O.Z * -1 + 350, (int)coordX + 768, (int)coordY * -1 + 350, DEFAULT_COLOR);
			}
			//Dividing Line
			screen.Line(SCREEN_SIZE, 0, SCREEN_SIZE, SCREEN_SIZE, DEFAULT_COLOR);
            //User Input
			application.UpdateCam(raytracer.camera);         
        }
예제 #7
0
 // Draws pixel on the screen with ability to zoom
 public void DrawScreenZoom()
 {
     // clear the screen
     screen.Clear(0);
     // you essentially draw a smaller segment of the field
     for (uint y = 0; y < screen.height / zoom; y++)
     {
         for (uint x = 0; x < screen.width / zoom; x++)
         {
             if (GetBit(x + xoffset, y + yoffset) == 1)
             {
                 // draw a white square per white bit
                 for (uint i = 0; i < zoom; i++)
                 {
                     for (uint j = 0; j < zoom; j++)
                     {
                         screen.Plot(x * zoom + i, y * zoom + j, 0xffffff);
                     }
                 }
             }
         }
     }
 }
예제 #8
0
        public void RenderGL()
        {
            for (int x = 0; x < screen.width - 1; x++)
            {
                for (int y = 0; y < screen.height - 1; y++)
                {
                    float rx = -1 + x * 2 / ((float)screen.width - 1);
                    float ry = -1 + y * 2 / ((float)screen.height - 1);
                    ray.O = new Vector2(rx, ry);

                    pixelColor = 0;
                    foreach (Light l in light_array)
                    {
                        float a      = l.light_pos.X - ray.O.X,
                                   b = l.light_pos.Y - ray.O.Y,
                                   distanceToLight = (float)Math.Sqrt(a * a + b * b);

                        ray.D = Vector2.Normalize(l.light_pos - ray.O);
                        ray.t = distanceToLight;

                        bool occluded = false;
                        foreach (Primitive p in primitives)
                        {
                            if (p.Intersect(ray))
                            {
                                occluded = true; break;
                            }
                        }
                        if (!occluded)
                        {
                            int red_int   = (int)(l.R * l.attentuation(distanceToLight) * 255),
                                green_int = (int)(l.G * l.attentuation(distanceToLight) * 255),
                                blue_int  = (int)(l.B * l.attentuation(distanceToLight) * 255);
                            pixelColor += (red_int << 16) + (green_int << 8) + blue_int;
                        }
                    }
                    screen.Plot(x, y, MathHelper.Clamp(pixelColor, 0, 16777215));
                    //Clamp the light so it is always between 0,0,0 (Black) and 255,255,255 (White)
                }
            }
        }
예제 #9
0
 // TICK
 // Main application entry point: the template calls this function once per frame.
 public void Tick()
 {
     // start timer
     timer.Restart();
     // run the simulation, 1 step
     Simulate();
     // visualize current state
     screen.Clear(0);
     for (uint y = 0; y < screen.height; y++)
     {
         for (uint x = 0; x < screen.width; x++)
         {
             if (GetBit(x + xoffset, y + yoffset) == 1)
             {
                 screen.Plot(x, y, 0xffffff);
             }
         }
     }
     // report performance
     Console.WriteLine("generation " + generation++ + ": " + timer.ElapsedMilliseconds + "ms");
 }
예제 #10
0
        // tick: renders one frame
        public void Tick()
        {
            screen.Clear(0);
            //Parallel.For is used for Multi- threading
            //Loop over all pixels in the screen
            Parallel.For(0, screen.height, (y) =>
            {
                Parallel.For(0, screen.width, (x) =>
                {
                    var color            = new Vector3();                           //Black to begin with
                    Vector2 ray_position = new Vector2(TransX(x), TransY(y));       //position on the screen

                    //for each pixel loop over the light sources
                    foreach (Light light in LightList)
                    {
                        //shoot a ray from each pixel to each existing light source
                        var ray = new Ray(ray_position, light.position - ray_position);

                        bool occluded = false;
                        //loop over all primitives that are in the world
                        foreach (IPrimitive p in PrimitiveList)
                        {
                            if (p.Intersect(ray))
                            {
                                occluded = true;
                            }
                        }
                        if (!occluded)
                        {
                            color += light.color * lightAttenuation(ray.t) * light.brightness;
                        }
                    }
                    screen.Plot(x, y, ToRGB32(color));
                });
            });
        }
예제 #11
0
        public void Tick()
        {

            for (int i = 0; i < 512; i++)
            {
                for (int j = 0; j < 512; j++)
                {
                    int location = j + i * 1024;
                    float u = j / 512f;
                    float v = i / 512f;

                    Vector3 floatcolor = tracer.Render(u, v);

                    int intcolor = getIntColor(floatcolor);

                    screen.pixels[location] = intcolor;


                }
            }

            //Debug Screen
            for (int k = 512; k < 1024; k++)
            {
                for (int l = 0; l < 512; l++)
                {
                    int location = k + l * 1024;
                    screen.pixels[location] = 0;
                }
            }

            //Draws every sphere, including its own offset and a bonus offset, so that the spheres don't cling to the edges.
            //Color offset is a cheap solution to give the spheres a different color each time.

            foreach (Sphere sphere in tracer.scene.sphereList)
            {
                int intcolor = getIntColor(sphere.material.color);
                for (int theta = 0; theta < 360; theta++)
                {
                    double xcord = sphere.rad * 5 * Math.Cos(theta);
                    double ycord = sphere.rad * 5 * Math.Sin(theta);
                    int offsetX = 5 * (int)sphere.spherePos.X;
                    int offsetZ = 5 * (int)sphere.spherePos.Z * -1;
                    screen.Plot((int)xcord + offsetX + 750, (int)ycord + offsetZ + 400, intcolor);
                }
            }

            //Draws the camera in the debug view
            screen.Plot((int)tracer.camera.cameraPos.X + 750, (int)tracer.camera.cameraPos.Z * -1 + 400, 0xff0000);

            foreach (Light light in tracer.scene.lightList)
            {
                screen.Plot((int)light.lightPos.X + 750, (int)light.lightPos.Z * -1 + 400, 0xcc66ff);
            }


            //Draws the primary rays in the debug view          
            for (int i = 0; i < tracer.raylist.Count; i++)
            {
                float t = 50;
                foreach (Primitive prim in tracer.scene.sphereList)
                {
                    Intersection intersect = prim.Intersect(tracer.raylist[i]);
                    if (intersect != null)
                    {
                        if (intersect.distance < t)
                        {
                            t = intersect.distance;
                        }
                    }
                }

                float primOx = tracer.raylist[i].Origin.X;
                float primOz = tracer.raylist[i].Origin.Z;

                float primTx = (primOx + t * tracer.raylist[i].Direction.X) * 5;
                float primTz = (primOz + t * tracer.raylist[i].Direction.Z) * 5;

                screen.Line((int)primOx + 750, (int)primOz * -1 + 400, (int)primTx + 750, (int)primTz * -1 + 400, 0xffff00);
            }
            tracer.raylist.Clear();
            

            //Draws a seperation line.
            screen.Line(512, 0, 512, 512, 0xff0000);

            app.MoveCam(tracer.camera);
        }
예제 #12
0
        // TICK
        // Main application entry point: the template calls this function once per frame.
        public void Tick()
        {
            GL.Finish();
            // start timer
            timer.Restart();
            //Initiate work sizes
            long[] workSize  = { pw, ph };
            long[] workSize2 = { pw *ph };
            //Set kernel arguments
            kernel.SetArgument(5, xoffset);
            kernel.SetArgument(6, yoffset);
            resolution = (int)(zoom * 512);
            long[] workSize3 = { resolution / 32, resolution };
            kernel.SetArgument(7, resolution);
            // run the simulation, 1 step
            screen.Clear(0);
            if (GLinterop)
            {
                if (resolution != oldResolution)
                {
                    image         = new OpenCLImage <int>(ocl, resolution, resolution);
                    oldResolution = resolution;
                }

                //set image as argument
                imageClearKernel.SetArgument(0, image);

                imageClearKernel.LockOpenGLObject(image.texBuffer);
                imageClearKernel.Execute(workSize3);
                imageClearKernel.UnlockOpenGLObject(image.texBuffer);

                //lock image object
                kernel.SetArgument(0, image);
                kernel.LockOpenGLObject(image.texBuffer);

                //run kernel
                kernel.Execute(workSize);

                //unlock image object
                kernel.UnlockOpenGLObject(image.texBuffer);

                secondKernel.Execute(workSize2);
            }
            else
            {
                kernel.SetArgument(0, buffer);
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = 0;
                }
                buffer.CopyToDevice();
                kernel.Execute(workSize);
                secondKernel.Execute(workSize2);
                buffer.CopyFromDevice();
                for (uint y = 0; y < screen.height; y++)
                {
                    for (uint x = 0; x < screen.width; x++)
                    {
                        screen.Plot(x, y, buffer[x + y * 512]);
                    }
                }
            }
            // visualize current state
            // report performance
            Console.WriteLine("generation " + generation++ + ": " + timer.ElapsedMilliseconds + "ms");
            //Console.ReadLine();
        }
        // Render: renders one frame
        public void Render()
        {
            screen.Clear(0);
            Vector3 Color;

            //render screens
            for (int y = 0; y < screen.height; y++)
            {
                for (int x = 0; x < screen.width; x++)
                {
                    //Create primary ray
                    Ray ray;
                    ray.t = 30;
                    ray.O = camera.CamPos;
                    ray.D = screen.pos0 + (x * ((screen.pos1 - screen.pos0) / 512.0f)) + (y * ((screen.pos2 - screen.pos0) / 512.0f));
                    //ray normalized direction
                    ray.D = (ray.D - camera.CamPos).Normalized();

                    Intersection nearest    = null;
                    Intersection nearestref = null;

                    foreach (Primitive p in prims)
                    {
                        Intersection overr = p.Intersection(ref ray);

                        if (overr != null)
                        {
                            nearest = overr;
                        }
                    }

                    // if there is an intersection, create a shadow ray
                    if (nearest != null)
                    {
                        //Check if the material is reflective
                        if (nearest.isMirror == false)
                        {
                            Color = CastShadowRay(nearest);
                        }
                        else
                        {
                            Color = CastShadowRay(nearest) * (1 - recursive / 100);
                            //Create reflection ray
                            Ray reflectionRay;
                            reflectionRay.D = ray.D - 2 * nearest.N * (Vector3.Dot(ray.D, nearest.N));
                            reflectionRay.O = nearest.I + reflectionRay.D * 0.0001f;
                            reflectionRay.t = 300;

                            foreach (Primitive p in prims)
                            {
                                Intersection overr = p.Intersection(ref reflectionRay);

                                if (overr != null)
                                {
                                    nearestref = overr;
                                }
                            }

                            Vector3 Color2 = Vector3.Zero;

                            if (nearestref != null)
                            {
                                //check if the nearest reflected object is reflective to
                                if (nearestref.isMirror)
                                {
                                    if (recursive != 100)
                                    {
                                        Color2 = CastShadowRay(nearestref) * (recursive / 100.0f);
                                    }
                                }
                                else
                                {
                                    Color2 = CastShadowRay(nearestref) * (recursive / 100.0f);
                                }
                            }
                            else
                            {
                                Color2 = Vector3.Zero;
                            }

                            Color = Color + Color2;


                            //draw reflectionrays on debug screen.
                            if (x % 20 == 0 && y == screen.height / 2)
                            {
                                screenDebug.Line(CordxTrans(reflectionRay.O.X), CordzTrans(reflectionRay.O.Z), CordxTrans(reflectionRay.D.X * ray.t), CordzTrans(reflectionRay.D.Z * ray.t), 0xff00ff);
                            }
                        }
                    }
                    else
                    {
                        Color = Vector3.Zero;
                    }


                    //plot the correct color on the correct pixel
                    screen.Plot(x, y, Color);

                    //Draw 1 in 10 rays on the debugscreen
                    if (x % 20 == 0 && y == screen.height / 2)
                    {
                        screenDebug.Line(CordxTrans(camera.CamPos.X), CordzTrans(camera.CamPos.Z), CordxTrans(ray.D.X * ray.t + camera.CamPos.X), CordzTrans(ray.D.Z * ray.t + camera.CamPos.Z), 0xffff00);
                    }
                }
            }


            //Draw Debug screen
            //Draw line between screen and debug screen
            screenDebug.Line(0, 0, 0, 1024, 0xffffff);
            //Draw camera as 2 orange lines
            screenDebug.Line(CordxTrans(camera.CamPos.X) - 5, CordzTrans(camera.CamPos.Y) - 1, CordxTrans(camera.CamPos.X) + 5, CordzTrans(camera.CamPos.Y) - 1, 0xffa500);
            screenDebug.Line(CordxTrans(camera.CamPos.X) - 5, CordzTrans(camera.CamPos.Y) + 1, CordxTrans(camera.CamPos.X) + 5, CordzTrans(camera.CamPos.Y) + 1, 0xffa500);
            //Draw screen as a blue line
            screenDebug.Line(CordxTrans(screen.pos1.X), CordzTrans(screen.pos1.Z), CordxTrans(screen.pos2.X), CordzTrans(screen.pos2.Z), 0x00ffff);
            //Draw spheres
            var sphere1 = GetSphere1;

            screenDebug.DrawSphere(sphere1);
            var sphere2 = GetSphere2;

            screenDebug.DrawSphere(sphere2);
            var sphere3 = GetSphere3;

            screenDebug.DrawSphere(sphere3);
        }
예제 #14
0
        // tick: renders one frame
        public void Tick()
        {
            screen.Clear(0);
            //move the lights
            if (dir % 2 == 0)
            {
                lightbuffer[0]  += TW(0.1f);
                lightbuffer[5]  -= TW(0.1f);
                lightbuffer[11] += TW(0.1f);
                lightbuffer[16] -= TW(0.1f);
            }
            else
            {
                lightbuffer[0]  -= TW(0.1f);
                lightbuffer[5]  += TW(0.1f);
                lightbuffer[11] -= TW(0.1f);
                lightbuffer[16] += TW(0.1f);
            }
            if (TW(worldsize) < lightbuffer[0] || lightbuffer[0] < TX(-worldsize))
            {
                dir++;
            }
            Thread t1 = new Thread(() =>
            {
                plot(TX((-worldsize + (0f / 8f * worldsize * 2))), TX((-worldsize + (1f / 8f * worldsize * 2))));
            });
            Thread t2 = new Thread(() =>
            {
                plot(TX((-worldsize + (1f / 8f * worldsize * 2))), TX((-worldsize + (2f / 8f * worldsize * 2))));
            });
            Thread t3 = new Thread(() =>
            {
                plot(TX((-worldsize + (2f / 8f * worldsize * 2))), TX((-worldsize + (3f / 8f * worldsize * 2))));
            });
            Thread t4 = new Thread(() =>
            {
                plot(TX((-worldsize + (3f / 8f * worldsize * 2))), TX((-worldsize + (4f / 8f * worldsize * 2))));
            });
            Thread t5 = new Thread(() =>
            {
                plot(TX((-worldsize + (4f / 8f * worldsize * 2))), TX((-worldsize + (5f / 8f * worldsize * 2))));
            });
            Thread t6 = new Thread(() =>
            {
                plot(TX((-worldsize + (5f / 8f * worldsize * 2))), TX((-worldsize + (6f / 8f * worldsize * 2))));
            });
            Thread t7 = new Thread(() =>
            {
                plot(TX((-worldsize + (6f / 8f * worldsize * 2))), TX((-worldsize + (7f / 8f * worldsize * 2))));
            });
            Thread t8 = new Thread(() =>
            {
                plot(TX((-worldsize + (7f / 8f * worldsize * 2))), (TX((-worldsize + (8f / 8f * worldsize * 2)))) - 1);
            });

            tarr[0] = t1;
            tarr[1] = t2;
            tarr[2] = t3;
            tarr[3] = t4;
            tarr[4] = t5;
            tarr[5] = t6;
            tarr[6] = t7;
            tarr[7] = t8;
            for (int td = 0; td < tarr.Length; td++)
            {
                tarr[td].Start();
            }
            for (int td = 0; td < tarr.Length; td++)
            {
                tarr[td].Join();
            }
            for (int i = 0; i < (screen.width - 1); i++)
            {
                for (int j = 0; j < (screen.height - 1); j++)
                {
                    screen.Plot(i, j, MixColor(MathHelper.Clamp(floatbuffer[i, j][0], 0, 1), MathHelper.Clamp(floatbuffer[i, j][1], 0, 1), MathHelper.Clamp(floatbuffer[i, j][2], 0, 1)));
                }
            }
            primitivesDraw();
        }
예제 #15
0
        // initialize
        public void Init()
        {
            float[] aax = { 0, 0.5f, 0, 0.5f };
            float[] aay = { 0, 0, 0.5f, 0.5f };

            light   = new List <Circle>();
            circles = new List <Circle>();
            squares = new List <Square>();

            circles.Add(new Circle(0.3f, 0.1f, 0.1f, false, new floatColour(0, 0, 0)));
            circles.Add(new Circle(-0.3f, 0.5f, 0.1f, false, new floatColour(0, 0, 0)));
            squares.Add(new Square(-0.3f, -0.3f, 0.2f, new floatColour(0, 0, 0)));
            light.Add(new Circle(0f, 0.5f, 0.25f, true, new floatColour(1, 0, 1)));
            light.Add(new Circle(-0.2f, 0.2f, 0.25f, true, new floatColour(0, 1, 0)));
            light.Add(new Circle(0.2f, -0.4f, 0.25f, true, new floatColour(0, 0, 1)));


            ray = new Ray();
            for (int x = 0; x < screen.width; x++)
            {
                for (int y = 0; y < screen.height; y++)
                {
                    floatColour[] pixelColour = { new floatColour(0, 0, 0), new floatColour(0, 0, 0), new floatColour(0, 0, 0), new floatColour(0, 0, 0) };
                    foreach (Circle c in light)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            ray.O = pixelPosition(x + aax[k], y + aay[k]);
                            ray.D = (new Vector2(ray.O.X - c.x, ray.O.Y - c.y)).Normalized();
                            ray.t = (float)Math.Sqrt(Math.Pow(ray.O.X - c.x, 2) + Math.Pow(ray.O.Y - c.y, 2));

                            bool occluded = false;
                            foreach (Circle p in circles)
                            {
                                if ((Math.Pow(ray.O.X - p.x, 2) + Math.Pow(ray.O.Y - p.y, 2)) > (p.r * p.r))
                                {
                                    if (ray.intersection(p))
                                    {
                                        occluded = true;
                                        float tmp = (float)Math.Sqrt((Math.Pow(c.x - p.x, 2) + Math.Pow(c.y - p.y, 2)));
                                        if (ray.t < tmp && (ray.t > 0 && tmp > 0))
                                        {
                                            occluded = false;
                                        }
                                        tmp = (float)Math.Sqrt((Math.Pow(ray.O.X - p.x, 2) + Math.Pow(ray.O.Y - p.y, 2)));
                                        if (ray.t < tmp)
                                        {
                                            occluded = false;
                                        }
                                    }
                                }
                                else
                                {
                                    occluded       = true;
                                    pixelColour[k] = new floatColour(0, 0, 0);
                                }
                            }
                            foreach (Square p in squares)
                            {
                                if (ray.intersection2(p))
                                {
                                    occluded = true;
                                    float tmp = (float)Math.Sqrt((Math.Pow(ray.O.X - (p.x + p.s), 2) + Math.Pow(ray.O.Y - (p.y + p.s), 2)));
                                    if (ray.t < tmp)
                                    {
                                        occluded = false;
                                    }
                                }
                            }
                            if (!occluded)
                            {
                                pixelColour[k] += c.colour * lightAttenuation(Vector2.Distance(ray.O, new Vector2(c.x, c.y)), c.r);
                            }
                        }
                    }
                    screen.Plot(x, y, ((pixelColour[0] + pixelColour[1] + pixelColour[2] + pixelColour[3]) / 4.0f).ToRGB32());
                }
            }
        }
예제 #16
0
        // tick: renders one frame
        public void Tick()
        {
            for (int i = 0; i < _lights.Length; i++)
            {
                _lights[i].Location = Tools.MoveUp(0.05f, _lights[i].Location);
            }

            Parallel.For(0, (screen.width + 1) * (screen.height + 1), k =>
            {
                int x    = k % (screen.width + 1);
                int y    = k / (screen.width + 1);
                float tx = (float)2 * x / (screen.width + 1) - 1;
                float ty = -((float)2 * y / (screen.height + 1) - 1);

                Vector2 location   = new Vector2(tx, ty);
                Vector3 pixelColor = new Vector3(0, 0, 0);

                if (location.LengthSquared() < 1)
                {
                    for (int i = 0, im = _lights.Length; i < im; i++)
                    {
                        Light light   = _lights[i];
                        Ray ray       = new Ray(location, Tools.Project(light.Location));
                        bool occluded = false;
                        float shade   = 0;

                        for (int j = 0, jm = _primitives.Length; !occluded && j < jm; j++)
                        {
                            if (_primitives[j].Intersects(ray, out bool locked))
                            {
                                occluded = true;
                                shade   *= locked ? 0 : 0.5f;
                            }
                        }

                        if (!occluded)
                        {
                            shade = LightAttenuation(ray.Distance);
                        }

                        pixelColor += light.Color * shade;
                    }
                }
                preBlend[x, y] = pixelColor;
            });

            // blend!
            Parallel.For(0, screen.height * screen.width, k =>
            {
                int x = k % screen.width;
                int y = k / screen.width;

                Vector3 pixelColor = new Vector3(0, 0, 0);
                pixelColor        += preBlend[x, y];
                pixelColor        += preBlend[x + 1, y];
                pixelColor        += preBlend[x, y + 1];
                pixelColor        += preBlend[x + 1, y + 1];
                pixelColor        /= 4;

                screen.Plot(x, y, MixColor(pixelColor));
            });

            /*
             * Ray ray2 = new Ray(new Vector2(0, 0.25f), new Vector2(0.25f, 0));
             * screen.Box(500 - 2, 400 - 2, 500 + 2, 400 + 2, MixColor(new Vector3(0, 0, 255)));
             * screen.Box(400 - 2, 300 - 2, 400 + 2, 300 + 2, MixColor(new Vector3(0, 0, 255)));
             * ray2.Draw(screen);
             * Console.WriteLine(_primitives[0].Intersects(ray2, out bool temp));
             */
        }