Пример #1
0
        // sample: samples a single path up to a maximum depth
        private Vector3 Sample(Ray ray, int depth, int x, int y)
        {
            // find nearest ray/scene intersection
            Scene.Intersect(ray);
            if (ray.objIdx == -1)
            {
                // no scene primitive encountered; skybox
                return(1.0f * scene.SampleSkydome(ray.D));
            }
            // calculate intersection point
            Vector3 I = ray.O + ray.t * ray.D;
            // get material at intersection point
            Material material = scene.GetMaterial(ray.objIdx, I);

            if (material.emissive)
            {
                // hit light
                return(material.diffuse);
            }
            // terminate if path is too long
            if (depth >= MAXDEPTH)
            {
                return(Vector3.Zero);
            }
            // handle material interaction
            float   r0 = RTTools.RandomFloat();
            Vector3 R  = Vector3.Zero;

            if (r0 < material.refr)
            {
                // dielectric: refract or reflect
                RTTools.Refraction(ray.inside, ray.D, ray.N, ref R);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);
                extensionRay.inside = (Vector3.Dot(ray.N, R) < 0);

                return(material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
            else if ((r0 < (material.refl + material.refr)) && (depth < MAXDEPTH))
            {
                // pure specular reflection
                R = Vector3.Reflect(ray.D, ray.N);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);

                return(material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
            else
            {
                // diffuse reflection
                if (x == 500 && y == 400)
                {
                    //Console.WriteLine("test");
                    //return new Vector3(255,255,255);
                }
                R = RTTools.DiffuseReflection(RTTools.GetRNG(), ray.N);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);
                return(Vector3.Dot(R, ray.N) * material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
        }
Пример #2
0
	// tick: renders one frame
	public void Tick()
	{
		// initialize timer
		if (firstFrame)
		{
			timer.Reset();
			timer.Start();
			firstFrame = false;
		}
		// handle keys, only when running time set to -1 (infinite)
		if (runningTime == -1) if (camera.HandleInput())
		{
			// camera moved; restart
			ClearAccumulator();
		}
		// render
		if (false) // if (useGPU)
		{
			// add your CPU + OpenCL path here
			// mind the gpuPlatform parameter! This allows us to specify the platform on our
			// test system.
			// note: it is possible that the automated test tool provides you with a different
			// platform number than required by your hardware. In that case, you can hardcode
			// the platform during testing (ignoring gpuPlatform); do not forget to put back
			// gpuPlatform before submitting!
		}
		else
		{
			// this is your CPU only path
			float scale = 1.0f / (float)++spp;
			for( int y = 0; y < screen.height; y++ )
			{
				for( int x = 0; x < screen.width; x++ )
				{
					// generate primary ray
					Ray ray = camera.Generate( RTTools.GetRNG(), x, y );
					// trace path
					int pixelIdx = x + y * screen.width;
					accumulator[pixelIdx] += Sample( ray, 0 );
					// plot final color
					screen.pixels[pixelIdx] = RTTools.Vector3ToIntegerRGB( scale * accumulator[pixelIdx] );
				}
			}
		}
		// stop and report when max render time elapsed
		int elapsedSeconds = (int)(timer.ElapsedMilliseconds / 1000);
		if (runningTime != -1) if (elapsedSeconds >= runningTime)
		{
			OpenTKApp.Report( (int)timer.ElapsedMilliseconds, spp, screen );
		}
	}
Пример #3
0
        static public void Refraction(bool inside, Vector3 D, Vector3 N, ref Vector3 R)
        {
            float nc = inside ? 1 : 1.2f, nt = inside ? 1.2f : 1;
            float nnt = nt / nc, ddn = Vector3.Dot(D, N);
            float cos2t = 1.0f - nnt * nnt * (1 - ddn * ddn);

            R = Vector3.Reflect(D, N);
            if (cos2t >= 0)
            {
                float r1 = RTTools.RandomFloat();
                float a = nt - nc, b = nt + nc, R0 = a * a / (b * b), c = 1 + ddn;
                float Tr = 1 - (R0 + (1 - R0) * c * c * c * c * c);
                if (r1 < Tr)
                {
                    R = (D * nnt - N * (ddn * nnt + (float)Math.Sqrt(cos2t)));
                }
            }
        }
Пример #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);

            // 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;
            }
        }
Пример #5
0
        // tick: renders one frame
        public void Tick()
        {
            // initialize timer
            if (firstFrame)
            {
                timer.Reset();
                timer.Start();
                firstFrame = false;
            }
            // handle keys, only when running time set to -1 (infinite)
            if (runningTime == -1)
            {
                if (camera.HandleInput())
                {
                    // camera moved; restart
                    ClearAccumulator();
                }
            }
            // render
            if (false)     // if (useGPU)
            {
                // add your CPU + OpenCL path here
                // mind the gpuPlatform parameter! This allows us to specify the platform on our
                // test system.
                // note: it is possible that the automated test tool provides you with a different
                // platform number than required by your hardware. In that case, you can hardcode
                // the platform during testing (ignoring gpuPlatform); do not forget to put back
                // gpuPlatform before submitting!
                long[] workSize  = { screen.width, screen.height };
                long[] localSize = { 16, 2 };
                queue.Execute(kernel, null, workSize, null, null);
                queue.Finish();

                queue.ReadFromBuffer(outputBuffer, ref screen.pixels, true, null);
                Console.WriteLine(screen.pixels[0]);

                Random r = RTTools.GetRNG();
                for (int i = 0; i < 1000; i++)
                {
                    randoms[i] = (float)r.NextDouble();
                }
                rndBuffer    = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms);
                cameraBuffer = new ComputeBuffer <Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL());
                kernel.SetMemoryArgument(6, cameraBuffer);
                kernel.SetMemoryArgument(7, rndBuffer);
            }
            else
            {
                // this is your CPU only path
                float scale = 1.0f / (float)++spp;

                Parallel.For(0, screen.height, y => {
                    for (int x = 0; x < screen.width; x++)
                    {
                        // generate primary ray
                        Ray ray = camera.Generate(RTTools.GetRNG(), x, y);
                        // trace path
                        int pixelIdx           = x + y * screen.width;
                        accumulator[pixelIdx] += Sample(ray, 0, x, y);
                        // plot final color
                        screen.pixels[pixelIdx] = RTTools.Vector3ToIntegerRGB(scale * accumulator[pixelIdx]);
                    }
                });
            }
            // stop and report when max render time elapsed
            int elapsedSeconds = (int)(timer.ElapsedMilliseconds / 1000);

            if (runningTime != -1)
            {
                if (elapsedSeconds >= runningTime)
                {
                    OpenTKApp.Report((int)timer.ElapsedMilliseconds, spp, screen);
                }
            }
        }
Пример #6
0
        // tick: renders one frame
        public void Tick()
        {
            //float t = 21.5f;
            // initialize timer
            if (firstFrame)
            {
                timer.Reset();
                timer.Start();
                firstFrame = false;
            }
            // handle keys, only when running time set to -1 (infinite)
            if (runningTime == -1) 
                if (camera.HandleInput())
                {
                    // camera moved; restart
                    ClearAccumulator();
                }
            // render
            if (useGPU)
            {
                
                // add your CPU + OpenCL path here
                // mind the gpuPlatform parameter! This allows us to specify the platform on our
                // test system.
                // note: it is possible that the automated test tool provides you with a different
                // platform number than required by your hardware. In that case, you can hardcode
                // the platform during testing (ignoring gpuPlatform); do not forget to put back
                // gpuPlatform before submitting!
                GL.Finish();
                // clear the screen
                screen.Clear(0);

                // do opencl stuff
                if (GLInterop)
                {
                    kernel.SetMemoryArgument(0, texBuffer);
                }
                else
                {
                    kernel.SetMemoryArgument(0, buffer);
                }
                
                // execute kernel
                //long[] workSize = { screen.width, screen.height };
                long[] localSize = { 8, 12 };
                long [] workSize = { screen.width , screen.height };
                if (GLInterop)
                {
                    List<ComputeMemory> c = new List<ComputeMemory>() { texBuffer };
                    queue.AcquireGLObjects(c, null);
                    queue.Execute(kernel, null, workSize, localSize, null);
                    queue.Finish();
                    queue.ReleaseGLObjects(c, null);
                }
                else
                {
                    camera.Update();
                    gpuCamera = new GPUCamera(camera.pos, camera.p1, camera.p2, camera.p3, camera.up, camera.right, screen.width, screen.height, camera.lensSize);
                    float scale = 1.0f / (float)++spp;
                    kernel.SetValueArgument(2, gpuCamera);
                    kernel.SetValueArgument(3, scale);
                    queue.Execute(kernel, null, workSize, localSize, null);
                    queue.Finish();
                    // fetch results
                    if (!GLInterop)
                    {
                        queue.ReadFromBuffer(buffer, ref data, true, null);

                        // visualize result
                        for (int y = 0; y < screen.height; y++) 
                            for (int x = 0; x < screen.width; x++)
                            {
                                int temp = x + y * screen.width;
                                screen.pixels[temp] = data[temp];
                            }
                    }
                }
            }
            else
            {
                // this is your CPU only path
                float scale = 1.0f / (float)++spp;
                Parallel.For(0, dataArray.Length, parallelOptions, (id) =>
                {
                    for (int j = dataArray[id].y1; j < dataArray[id].y2 && j < screen.height; j++)
                    {
                        for (int i = dataArray[id].x1; i < dataArray[id].x2 && i < screen.width; i++)
                        {
                            // generate primary ray
                            Ray ray = camera.Generate(RTTools.GetRNG(), i, j);
                            // trace path
                            int pixelIdx = i + j * screen.width;
                            accumulator[pixelIdx] += Sample(ray, 0);
                            // plot final color
                            screen.pixels[pixelIdx] = RTTools.Vector3ToIntegerRGB(scale * accumulator[pixelIdx]);
                        }
                    }
                });
            }

            // stop and report when max render time elapsed
            int elapsedSeconds = (int)(timer.ElapsedMilliseconds / 1000);
            if (runningTime != -1) if (elapsedSeconds >= runningTime)
                {
                    OpenTKApp.Report((int)timer.ElapsedMilliseconds, spp, screen);
                }
        }