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); }
// 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); }
// 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); }
// 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 }
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); } }); }
// 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 ); }
//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; }
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); }
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; } }
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; }
// 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. }
//Constructor. public static void CreateDebug(Scene sce, Surface scr) { Rays = new List<Ray>(); scene = sce; screen = scr; }