// 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); }