//// =========================================================================================================== //// Methods //// =========================================================================================================== public async Task <BitmapSource> RenderAsync( double dpiX, double dpiY, int maxDegreeOfParallelism = -1, IProgress <SceneRenderProgress>?progress = null, CancellationToken cancellationToken = default) { _progress = progress; _bitmap = new WriteableBitmap(CanvasWidth, CanvasHeight, dpiX, dpiY, PixelFormats.Bgr24, null); try { // Render the scene. var renderProgress = new Progress <RenderProgressStep>(OnRenderProgress); var options = new CameraRenderOptions(maxDegreeOfParallelism, renderProgress, cancellationToken); Canvas canvas = await Task.Run(() => Render(options), cancellationToken); canvas.RenderToWriteableBitmap(_bitmap); ReportProgress(100); return(_bitmap); } finally { _progress = null; _bitmap = null; } }
protected override Canvas Render(CameraRenderOptions options) { var floor = new Plane(material: new Material(new Color(1, 0.9, 0.9)).WithSpecular(0)); var middle = new Sphere( "Middle", Matrix4x4.CreateTranslation(-0.5, 1, 0.5), new Material(new Color(0.1, 1, 0.5), diffuse: 0.7, specular: 0.3) ); var right = new Sphere( "Right", Matrix4x4.CreateScaling(0.5, 0.5, 0.5).Translate(1.5, 0.5, -0.5), new Material(new Color(0.5, 1, 0.1), diffuse: 0.7, specular: 0.3) ); var left = new Sphere( "Left", Matrix4x4.CreateScaling(0.33, 0.33, 0.33).Translate(-1.5, 0.33, -0.75), new Material(new Color(1, 0.8, 0.1), diffuse: 0.7, specular: 0.3) ); var light = new PointLight(new Point(-10, 10, -10), Colors.White); var world = new World(light, floor, middle, right, left); var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 1.5, -5), new Point(0, 1, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, Math.PI / 3, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { // Floor var floor = new Plane( transform: Matrix4x4.CreateTranslation(0, -NumberExtensions.Epsilon, 0), material: new Material( pattern: new CheckerPattern( Colors.Gray, Colors.DarkGray, Matrix4x4.CreateScaling(0.25, 0.25, 0.25)), ambient: 0.2, diffuse: 0.9, specular: 0)); var pyramid = CreatePyramid(); pyramid.Material = new Material(Colors.Yellow, ambient: 0.2, diffuse: 0.9, specular: 0); // Lights, camera, action. var light = new PointLight(new Point(1, 7, -5), Colors.White); var world = new World(light, floor, pyramid); var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 3.5, -9), new Point(0, 0.3, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 0.314, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
//// =========================================================================================================== //// Methods //// =========================================================================================================== protected override Canvas Render(CameraRenderOptions options) { var start = new Point(0, 1, 0); var velocity = new Vector(1, 1.8, 0).Normalize() * 11.25; var cannonball = new Projectile(start, velocity); // gravity is -0.1 unit/tick and wind is -0.01 unit/tick var gravity = new Vector(0, -0.1, 0); var wind = new Vector(-0.01, 0, 0); var environment = new Environment(gravity, wind); var color = Colors.Magenta; const int pixelBorderSize = 2; var canvas = new MutableCanvas(CanvasWidth, CanvasHeight); while (cannonball.Position.Y > 0) { cannonball = Tick(environment, cannonball); int pointX = (int)Math.Round(cannonball.Position.X); int pointY = (int)Math.Round(canvas.Height - cannonball.Position.Y); canvas.FillRect( top: pointY - pixelBorderSize, left: pointX - pixelBorderSize, bottom: pointY + pixelBorderSize, right: pointX + pixelBorderSize, color); } return(canvas.ToImmutable()); }
protected override Canvas Render(CameraRenderOptions options) { var canvas = new MutableCanvas(CanvasWidth, CanvasHeight); int centerX = canvas.Width / 2; int centerY = canvas.Height / 2; double clockRadius = Math.Min(canvas.Width * (3d / 8), canvas.Height * (3d / 8)); var color = Colors.Cyan; const int pixelBorderSize = 4; // The clock is oriented along the y axis, which means when looking at it face-on you're looking // towards the negative y axis and the clock face sits on the x-z plane. var twelve = new Point(0, 0, 1); const double rotationAngle = (2 * Math.PI) / 12; for (int hour = 0; hour < 12; hour++) { // Rotate the twelve point around the y axis. // Scale by the clock radius. // Translate to the center of the canvas. var transform = Matrix4x4.CreateRotationY(hour * rotationAngle); Point hourPoint = transform * twelve; int x = centerX + (int)Math.Round(hourPoint.X * clockRadius); int y = centerY - (int)Math.Round(hourPoint.Z * clockRadius); canvas.FillRect( top: y - pixelBorderSize, left: x - pixelBorderSize, bottom: y + pixelBorderSize, right: x + pixelBorderSize, color); } return(canvas.ToImmutable()); }
protected override Canvas Render(CameraRenderOptions options) { // Patterns var checkerPattern = new PerturbedPattern(new CheckerPattern(new Color(0.8, 1, 0.8), Colors.Green)); var stripePattern = new PerturbedPattern( new StripePattern( Colors.Blue, new Color(0.8, 0.8, 1), Matrix4x4.CreateScaling(0.25, 0.25, 0.25) .RotateZ(-Math.PI / 4) .RotateY(-Math.PI / 6) .Translate(0.4, 0, 0))); var gradientPattern = new PerturbedPattern( new RadialGradientPattern( Colors.Green, Colors.Yellow, Matrix4x4.CreateScaling(0.25, 0.25, 0.25).RotateX(-Math.PI / 2))); var ringPattern = new PerturbedPattern( new RingPattern( Colors.Red, Colors.White, Matrix4x4.CreateScaling(0.15, 0.15, 0.15).RotateX(-Math.PI / 2))); // Shapes var floor = new Plane( "Floor", Matrix4x4.CreateRotationY(Math.PI / 4), new Material(pattern: checkerPattern, specular: 0)); var left = new Sphere( "Left", Matrix4x4.CreateScaling(0.33, 0.33, 0.33).Translate(-2, 0.33, -0.75), new Material(pattern: ringPattern, diffuse: 0.7, specular: 0.3)); var middle = new Sphere( "Middle", Matrix4x4.CreateTranslation(-0.5, 1, 0.5), new Material(pattern: stripePattern, diffuse: 0.7, specular: 0.3)); var right = new Sphere( "Right", Matrix4x4.CreateScaling(0.5, 0.5, 0.5).Translate(1.5, 0.5, -0.5), new Material(pattern: gradientPattern, diffuse: 0.7, specular: 0.3)); var light = new PointLight(new Point(-10, 10, -10), Colors.White); var world = new World(light, floor, left, middle, right); var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 1.5, -5), new Point(0, 1, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, Math.PI / 3, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { var canvas = new MutableCanvas(CanvasWidth, CanvasHeight); var sphere = new Sphere(); var rayOrigin = new Point(0, 0, -5); const double wallZ = 10; const double wallSize = 7.0; double pixelSize = wallSize / canvas.Width; const double halfWallSize = wallSize / 2; double totalPixels = canvas.Width * canvas.Height; // For each row of pixels in the canvas... for (int y = 0; y < canvas.Height; y++) { // Compute the world y coordinate (top = +half, bottom = -half). double worldY = halfWallSize - (pixelSize * y); // For each pixel in the row... for (int x = 0; x < canvas.Width; x++) { // See if we should stop. if (options.CancellationToken.IsCancellationRequested) { return(canvas.ToImmutable()); } // Compute the world x coordinate (left = -half, right = +half). double worldX = -halfWallSize + (pixelSize * x); // Describe the point on the wall that the ray will target. var position = new Point(worldX, worldY, wallZ); // Cast the ray into the scene to see what it hits. var ray = new Ray(rayOrigin, (position - rayOrigin).Normalize()); var intersections = sphere.Intersect(ray); if (intersections.Hit != null) { canvas.SetPixel(x, y, Colors.Red); } } // Report the progress. double pixelsRendered = (y * CanvasWidth) + CanvasWidth; int percentComplete = (int)Math.Round((pixelsRendered / totalPixels) * 100.0); options.Progress?.Report(new RenderProgressStep(percentComplete, y, canvas.GetRow(y))); } return(canvas.ToImmutable()); }
protected override Canvas Render(CameraRenderOptions options) { var sphereMaterial = new Material(ambient: 0.2, diffuse: 0.8, specular: 0.3, shininess: 200); var wristMaterial = sphereMaterial.WithColor(new Color(0.1, 1, 1)); var palmMaterial = sphereMaterial.WithColor(new Color(0.1, 0.1, 1)); var thumbMaterial = palmMaterial; var indexMaterial = sphereMaterial.WithColor(new Color(1, 1, 0.1)); var middleMaterial = sphereMaterial.WithColor(new Color(0.1, 1, 0.5)); var ringMaterial = sphereMaterial.WithColor(new Color(0.1, 1, 0.1)); var pinkyMaterial = sphereMaterial.WithColor(new Color(0.1, 0.5, 1)); var backdrop = new Sphere( "Backdrop", Matrix4x4.CreateScaling(200, 200, 0.01).Translate(0, 0, 20), new Material(Colors.White, ambient: 0, diffuse: 0.5, specular: 0)); var wrist = new Sphere( "Wrist", Matrix4x4.CreateScaling(3, 3, 3).Translate(-4, 0, -21).RotateZ(Math.PI / 4), wristMaterial); var palm = new Sphere("Palm", Matrix4x4.CreateScaling(4, 3, 3).Translate(0, 0, -15), palmMaterial); var thumb = new Sphere("Thumb", Matrix4x4.CreateScaling(1, 3, 1).Translate(-2, 2, -16), thumbMaterial); var index = new Sphere("Index", Matrix4x4.CreateScaling(3, 0.75, 0.75).Translate(3, 2, -22), indexMaterial); var middle = new Sphere( "Middle", Matrix4x4.CreateScaling(3, 0.75, 0.75).Translate(4, 1, -19), middleMaterial); var ring = new Sphere("Ring", Matrix4x4.CreateScaling(3, 0.75, 0.75).Translate(4, 0, -18), ringMaterial); var pinky = new Sphere( "Pinky", Matrix4x4.CreateScaling(2.5, 0.6, 0.6) .Translate(1, 0, 0) .RotateZ(Math.PI / 10) .Translate(3, -1.5, -20), pinkyMaterial); var light = new PointLight(new Point(0, 0, -100), Colors.White); var world = new World(light, backdrop, wrist, palm, thumb, index, middle, ring, pinky); var cameraTransform = Matrix4x4.CreateLookAt(new Point(40, 0, -70), new Point(0, 0, -5), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, 0.524, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { // Shapes var backdrop = new Plane( "Backdrop", Matrix4x4.CreateRotationX(Math.PI / 2).Translate(0, 0, 100), new Material(Colors.White, ambient: 1, diffuse: 0, specular: 0)); var ufo1 = CreateUfo() .ChangeTransform(Matrix4x4.CreateRotationY(0.1745).RotateX(0.4363).Translate(-2.8, 0, 0)) .ChangeMaterial( new Material(new Color(0.9, 0.2, 0.4), ambient: 0.2, diffuse: 0.8, specular: 0.7, shininess: 20)); var ufo2 = CreateUfo() .ChangeTransform(Matrix4x4.CreateRotationY(0.1745)) .ChangeMaterial( new Material(new Color(0.2, 0.9, 0.6), ambient: 0.2, diffuse: 0.8, specular: 0.7, shininess: 20)); var ufo3 = CreateUfo() .ChangeTransform(Matrix4x4.CreateRotationY(-0.1745).RotateX(-0.4363).Translate(2.8, 0, 0)) .ChangeMaterial( new Material(new Color(0.2, 0.3, 1), ambient: 0.2, diffuse: 0.8, specular: 0.7, shininess: 20)); // Lights var light1 = new PointLight(new Point(10_000, 10_000, -10_000), Colors.DarkGray); var light2 = new PointLight(new Point(-10_000, 10_000, -10_000), Colors.DarkGray); var light3 = new PointLight(new Point(10_000, -10_000, -10_000), Colors.DarkGray); var light4 = new PointLight(new Point(-10_000, -10_000, -10_000), Colors.DarkGray); // Create the world. var world = new World(new[] { light1, light2, light3, light4 }, new[] { backdrop, ufo1, ufo2, ufo3 }); // Create the camera. var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 0, -9), new Point(0, 0, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 0.9, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { // Patterns var map1 = new ColorMap(new ColorMapEntry(0, Colors.White)); var floorPattern = new PerlinPattern(map1, transform: Matrix4x4.CreateTranslation(-1000, 0, 0)); // Shapes var floor = new Plane( "Floor", Matrix4x4.CreateRotationY(Math.PI / 4), new Material(pattern: floorPattern, specular: 0)); var left = new Sphere( "Left", Matrix4x4.CreateScaling(0.33, 0.33, 0.33).Translate(-2, 0.33, -0.75), new Material(pattern: floorPattern, diffuse: 0.7, specular: 0.3)); var middle = new Sphere( "Middle", Matrix4x4.CreateTranslation(-0.5, 1, 0.5), new Material(pattern: floorPattern, diffuse: 0.7, specular: 0.3)); var right = new Sphere( "Right", Matrix4x4.CreateScaling(0.5, 0.5, 0.5).Translate(1.5, 0.5, -0.5), new Material(pattern: floorPattern, diffuse: 0.7, specular: 0.3)); var light = new PointLight(new Point(-10, 10, -10), Colors.White); var world = new World(light, floor, left, middle, right); var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 1.5, -5), new Point(0, 1, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, Math.PI / 3, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { // Materials var wallMaterial = new Material( pattern: new StripePattern( new Color(0.45, 0.45, 0.45), new Color(0.55, 0.55, 0.55), Matrix4x4.CreateScaling(0.25, 0.25, 0.25).RotateY(Math.PI / 2)), ambient: 0, diffuse: 0.4, specular: 0, reflective: 0.3); // Shapes var floor = new Plane( "Floor", Matrix4x4.CreateRotationY(0.31415), new Material( pattern: new CheckerPattern(new Color(0.35, 0.35, 0.35), new Color(0.65, 0.65, 0.65)), specular: 0, reflective: 0.4)); var ceiling = new Plane( "Ceiling", Matrix4x4.CreateTranslation(0, 5, 0), new Material(new Color(0.8, 0.8, 0.8), ambient: 0.3, specular: 0)); var westWall = new Plane( "WestWall", Matrix4x4.CreateRotationY(Math.PI / 2).RotateZ(Math.PI / 2).Translate(-5, 0, 0), wallMaterial); var eastWall = new Plane( "EastWall", Matrix4x4.CreateRotationY(Math.PI / 2).RotateZ(Math.PI / 2).Translate(5, 0, 0), wallMaterial); var northWall = new Plane("NorthWall", Matrix4x4.CreateRotationX(Math.PI / 2).Translate(0, 0, 5), wallMaterial); var southWall = new Plane("SouthWall", Matrix4x4.CreateRotationX(Math.PI / 2).Translate(0, 0, -5), wallMaterial); // Background hexagons var backHex1 = new Hexagon( "BackHex1", Matrix4x4.CreateRotationX(Math.PI / 2).Scale(0.4, 0.4, 0.4).Translate(4.6, 0.5, 1), new Material(new Color(0.8, 0.5, 0.3), shininess: 50)); var backHex2 = new Hexagon( "BackHex2", Matrix4x4.CreateRotationX(Math.PI / 2).Scale(0.3, 0.3, 0.3).Translate(4.7, 0.4, 0.4), new Material(new Color(0.9, 0.4, 0.5), shininess: 50)); var backHex3 = new Hexagon( "BackHex3", Matrix4x4.CreateRotationX(Math.PI / 2).Scale(0.5, 0.5, 0.5).Translate(-1, 0.6, 4.5), new Material(new Color(0.4, 0.9, 0.6), shininess: 50)); var backHex4 = new Hexagon( "BackHex4", Matrix4x4.CreateRotationX(Math.PI / 2).Scale(0.3, 0.3, 0.3).Translate(-1.7, 0.4, 4.7), new Material(new Color(0.4, 0.6, 0.9), shininess: 50)); // Foreground hexagons var redHex = new Hexagon( "RedHex", Matrix4x4.CreateRotationX(-Math.PI / 4).Translate(-0.6, 1.2, 0.6), new Material(new Color(1, 0.3, 0.2), specular: 0.4, shininess: 5)); var blueGlassHex = new Hexagon( "BlueGlassHex", Matrix4x4.CreateRotationX(-Math.PI / 3) .Scale(0.7, 0.7, 0.7) .Translate(0.6, 0.8, -0.6) .RotateY(Math.PI / 4), new Material( new Color(0, 0, 0.2), ambient: 0, diffuse: 0.4, specular: 0.9, shininess: 300, reflective: 0.9, transparency: 0.9, refractiveIndex: 1.5)); var greenGlassHex = new Hexagon( "GreenGlassHex", Matrix4x4.CreateScaling(0.5, 0.5, 0.5).Translate(-0.7, 0.6, -0.8), new Material( new Color(0, 0.2, 0), ambient: 0, diffuse: 0.4, specular: 0.9, shininess: 300, reflective: 0.9, transparency: 0.9, refractiveIndex: 1.5)); // Lights, camera, action. var light = new PointLight(new Point(-4.9, 4.9, -1), Colors.White); var world = new World( light, floor, ceiling, westWall, eastWall, northWall, southWall, backHex1, backHex2, backHex3, backHex4, redHex, blueGlassHex, greenGlassHex); var cameraTransform = Matrix4x4.CreateLookAt( new Point(-2.6, 1.5, -3.9), new Point(-0.6, 1, -0.8), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 1.152, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) {
protected override Canvas Render(CameraRenderOptions options) { // Shapes var floorCeiling = new Cube( "FloorCeiling", Matrix4x4.CreateTranslation(0, 1, 0).Scale(20, 7, 20), new Material( pattern: new CheckerPattern( Colors.Black, Colors.DarkGray, Matrix4x4.CreateScaling(0.07, 0.07, 0.07)), ambient: 0.25, diffuse: 0.7, specular: 0.9, shininess: 300, reflective: 0.1)); var walls = new Cube( "Walls", Matrix4x4.CreateScaling(10, 10, 10), new Material( pattern: new CheckerPattern( new Color(0.4863, 0.3765, 0.2941), new Color(0.3725, 0.2902, 0.2275), Matrix4x4.CreateScaling(0.05, 20, 0.05)), ambient: 0.1, diffuse: 0.7, specular: 0.9, shininess: 300, reflective: 0.1)); var csgUnion = new CsgShape( "Union", CsgOperation.Union, new Cube( "YellowCube", Matrix4x4.CreateTranslation(0, 1.5, 0), new Material(Colors.Yellow, diffuse: 0.7, specular: 0.3)), new Sphere( "RedSphere", Matrix4x4.CreateTranslation(0.6, 2, -0.6), new Material(Colors.Red, diffuse: 0.7, specular: 0.9)), transform: Matrix4x4.CreateRotationY(-Math.PI / 3).Translate(-4, 0, -2)); var csgIntersection = new CsgShape( "Intersection", CsgOperation.Intersection, new Cube( "YellowCube", Matrix4x4.CreateTranslation(0, 1.5, 0), new Material(Colors.Yellow, diffuse: 0.7, specular: 0.3)), new Sphere( "RedSphere", Matrix4x4.CreateTranslation(0.6, 2, -0.6), new Material(Colors.Red, diffuse: 0.7, specular: 0.9)), transform: Matrix4x4.CreateRotationY(-Math.PI / 2).Translate(0, 0, -2)); var csgDifference = new CsgShape( "Difference", CsgOperation.Difference, new Cube( "YellowCube", Matrix4x4.CreateTranslation(0, 1.5, 0), new Material(Colors.Yellow, diffuse: 0.7, specular: 0.3)), new Sphere( "RedSphere", Matrix4x4.CreateTranslation(0.6, 2, -0.6), new Material(Colors.Red, diffuse: 0.7, specular: 0)), transform: Matrix4x4.CreateRotationY(-Math.PI / 6).Translate(3, 0, 2)); // Lights, camera, action. var light = new PointLight(new Point(8, 8, -5), Colors.White); var world = new World(light, floorCeiling, walls, csgUnion, csgIntersection, csgDifference); var cameraTransform = Matrix4x4.CreateLookAt(new Point(8, 6, -8), new Point(0, 3, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 0.785, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { var canvas = new MutableCanvas(CanvasWidth, CanvasHeight); var sphere = new Sphere(material: new Material(new Color(1, 0.2, 1))); var lightPosition = new Point(-10, 10, -10); var lightColor = Colors.White; var light = new PointLight(lightPosition, lightColor); var rayOrigin = new Point(0, 0, -5); const int wallZ = 10; const double wallSize = 7.0; double pixelSize = wallSize / canvas.Width; const double halfWallSize = wallSize / 2; double totalPixels = canvas.Width * canvas.Height; // For each row of pixels in the canvas... for (int y = 0; y < canvas.Height; y++) { // Compute the world y coordinate (top = +half, bottom = -half). double worldY = halfWallSize - (pixelSize * y); // For each pixel in the row... for (int x = 0; x < canvas.Width; x++) { // See if we should stop. if (options.CancellationToken.IsCancellationRequested) { return(canvas.ToImmutable()); } // Compute the world x coordinate (left = -half, right = +half). double worldX = -halfWallSize + (pixelSize * x); // Describe the point on the wall that the ray will target. var position = new Point(worldX, worldY, wallZ); // Cast the ray into the scene to see what it hits. var ray = new Ray(rayOrigin, (position - rayOrigin).Normalize()); IntersectionList intersections = sphere.Intersect(ray); Intersection? hit = intersections.Hit; if (hit != null) { Point point = ray.PositionAt(hit.T); Vector normal = hit.Shape.NormalAt(point); Vector eye = ray.Direction.Negate(); Color color = hit.Shape.Material.CalculateLighting(hit.Shape, light, point, eye, normal, false); canvas.SetPixel(x, y, color); } } // Report the progress. double pixelsRendered = (y * CanvasWidth) + CanvasWidth; int percentComplete = (int)Math.Round((pixelsRendered / totalPixels) * 100.0); options.Progress?.Report(new RenderProgressStep(percentComplete, y, canvas.GetRow(y))); } return(canvas.ToImmutable()); }
protected override Canvas Render(CameraRenderOptions options) { var floor = new Sphere( "Floor", Matrix4x4.CreateScaling(10, 0.01, 10), new Material(new Color(1, 0.9, 0.9)).WithSpecular(0)); var leftWall = new Sphere( "LeftWall", Matrix4x4.CreateScaling(10, 0.01, 10) .RotateX(Math.PI / 2) .RotateY(-Math.PI / 4) .Translate(0, 0, 5), floor.Material ); var rightWall = new Sphere( "RightWall", Matrix4x4.CreateScaling(10, 0.01, 10) .RotateX(Math.PI / 2) .RotateY(Math.PI / 4) .Translate(0, 0, 5), floor.Material ); var middle = new Sphere( "Middle", Matrix4x4.CreateTranslation(-0.5, 1, 0.5), new Material(new Color(0.1, 1, 0.5), diffuse: 0.7, specular: 0.3) ); var right = new Sphere( "Right", Matrix4x4.CreateScaling(0.5, 0.5, 0.5).Translate(1.5, 0.5, -0.5), new Material(new Color(0.5, 1, 0.1), diffuse: 0.7, specular: 0.3) ); var left = new Sphere( "Left", Matrix4x4.CreateScaling(0.33, 0.33, 0.33).Translate(-1.5, 0.33, -0.75), new Material(new Color(1, 0.8, 0.1), diffuse: 0.7, specular: 0.3) ); var light1 = new PointLight(new Point(-10, 10, -10), Colors.White); var light2 = new PointLight(new Point(0, 10, -10), Colors.DarkGray); var light3 = new PointLight(new Point(10, 10, -10), Colors.DarkGray); var world = new World( new[] { light1, light2, light3 }, new[] { floor, leftWall, rightWall, middle, right, left }); var cameraTransform = Matrix4x4.CreateLookAt(new Point(0, 1.5, -5), new Point(0, 1, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, Math.PI / 3, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected override Canvas Render(CameraRenderOptions options) { // Colors var tableLegColor = new Color(0.5529, 0.4235, 0.3255); // Shapes var floorCeiling = new Cube( "FloorCeiling", Matrix4x4.CreateTranslation(0, 1, 0).Scale(20, 7, 20), new Material( pattern: new CheckerPattern( Colors.Black, Colors.DarkGray, Matrix4x4.CreateScaling(0.07, 0.07, 0.07)), ambient: 0.25, diffuse: 0.7, specular: 0.9, shininess: 300, reflective: 0.1)); var walls = new Cube( "Walls", Matrix4x4.CreateScaling(10, 10, 10), new Material( pattern: new CheckerPattern( new Color(0.4863, 0.3765, 0.2941), new Color(0.3725, 0.2902, 0.2275), Matrix4x4.CreateScaling(0.05, 20, 0.05)), ambient: 0.1, diffuse: 0.7, specular: 0.9, shininess: 300, reflective: 0.1)); var tableTop = new Cube( "TableTop", Matrix4x4.CreateScaling(3, 0.1, 2).Translate(0, 3.1, 0), new Material( pattern: new StripePattern( tableLegColor, new Color(0.6588, 0.5098, 0.4000), Matrix4x4.CreateRotationY(0.1).Scale(0.05, 0.05, 0.05)), ambient: 0.1, diffuse: 0.7, specular: 0.9, shininess: 300, reflective: 0.2)); var leg1 = new Cube( "Leg1", Matrix4x4.CreateScaling(0.1, 1.5, 0.1).Translate(2.7, 1.5, -1.7), new Material(tableLegColor, ambient: 0.2, diffuse: 0.7)); var leg2 = new Cube( "Leg2", Matrix4x4.CreateScaling(0.1, 1.5, 0.1).Translate(2.7, 1.5, 1.7), new Material(tableLegColor, ambient: 0.2, diffuse: 0.7)); var leg3 = new Cube( "Leg3", Matrix4x4.CreateScaling(0.1, 1.5, 0.1).Translate(-2.7, 1.5, -1.7), new Material(tableLegColor, ambient: 0.2, diffuse: 0.7)); var leg4 = new Cube( "Leg4", Matrix4x4.CreateScaling(0.1, 1.5, 0.1).Translate(-2.7, 1.5, 1.7), new Material(tableLegColor, ambient: 0.2, diffuse: 0.7)); var glassCube = new Cube( "GlassCube", Matrix4x4.CreateScaling(0.25, 0.25, 0.25).RotateY(0.2).Translate(0, 3.45001, 0), new Material( new Color(1, 1, 0.8), ambient: 0, diffuse: 0.3, specular: 0.9, shininess: 300, reflective: 0.7, transparency: 0.7, refractiveIndex: 1.5)) { IsShadowHidden = true }; var littleCube1 = new Cube( "LittleCube1", Matrix4x4.CreateScaling(0.15, 0.15, 0.15).RotateY(-0.4).Translate(1, 3.35, -0.9), new Material(new Color(1, 0.5, 0.5), diffuse: 0.4, reflective: 0.6)); var littleCube2 = new Cube( "LittleCube2", Matrix4x4.CreateScaling(0.15, 0.07, 0.15).RotateY(0.4).Translate(-1.5, 3.27, 0.3), new Material(new Color(1, 1, 0.5))); var littleCube3 = new Cube( "LittleCube3", Matrix4x4.CreateScaling(0.2, 0.05, 0.05).RotateY(0.4).Translate(0, 3.25, 1), new Material(new Color(0.5, 1, 0.5))); var littleCube4 = new Cube( "LittleCube4", Matrix4x4.CreateScaling(0.05, 0.2, 0.05).RotateY(0.8).Translate(-0.6, 3.4, -1), new Material(new Color(0.5, 0.5, 1))); var littleCube5 = new Cube( "LittleCube5", Matrix4x4.CreateScaling(0.05, 0.2, 0.05).RotateY(0.8).Translate(2, 3.4, 1), new Material(new Color(0.5, 1, 1))); var frame1 = new Cube( "Frame1", Matrix4x4.CreateScaling(0.05, 1, 1).Translate(-10, 4, 1), new Material(new Color(0.7098, 0.2471, 0.2196), diffuse: 0.6)); var frame2 = new Cube( "Frame2", Matrix4x4.CreateScaling(0.05, 0.4, 0.4).Translate(-10, 3.4, 2.7), new Material(new Color(0.2667, 0.2706, 0.6902), diffuse: 0.6)); var frame3 = new Cube( "Frame3", Matrix4x4.CreateScaling(0.05, 0.4, 0.4).Translate(-10, 4.6, 2.7), new Material(new Color(0.3098, 0.5961, 0.3098), diffuse: 0.6)); var mirrorFrame = new Cube( "MirrorFrame", Matrix4x4.CreateScaling(5, 1.5, 0.05).Translate(-2, 3.5, 9.95), new Material(new Color(0.3882, 0.2627, 0.1882), diffuse: 0.7)); var mirror = new Cube( "Mirror", Matrix4x4.CreateScaling(4.8, 1.4, 0.06).Translate(-2, 3.5, 9.95), new Material(Colors.Black, ambient: 0, diffuse: 0, specular: 1, shininess: 300, reflective: 1)); // Lights, camera, action. var light = new PointLight(new Point(0, 6.9, -5), new Color(1, 1, 0.9)); var world = new World( light, floorCeiling, walls, tableTop, leg1, leg2, leg3, leg4, glassCube, littleCube1, littleCube2, littleCube3, littleCube4, littleCube5, frame1, frame2, frame3, mirrorFrame, mirror); var cameraTransform = Matrix4x4.CreateLookAt(new Point(8, 6, -8), new Point(0, 3, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 0.785, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }
protected abstract Canvas Render(CameraRenderOptions options);
protected override Canvas Render(CameraRenderOptions options) { // Shapes var floor = new Plane(material: new Material( pattern: new CheckerPattern( Colors.Gray, Colors.DarkGray, Matrix4x4.CreateScaling(0.25, 0.25, 0.25).RotateY(0.3)), ambient: 0.2, diffuse: 0.9, specular: 0)); var blueCylinder = new Cone( "BlueCylinder", minimumY: 0, maximumY: 0.75, isClosed: true, Matrix4x4.CreateScaling(0.5, 1, 0.5).Translate(-1, 0, 1), new Material(new Color(0, 0, 0.6), diffuse: 0.1, specular: 0.9, shininess: 300, reflective: 0.9)); // Concentric Cylinders var outer = new Cone( minimumY: 0, maximumY: 0.2, transform: Matrix4x4.CreateScaling(0.8, 1, 0.8).Translate(1, 0, 0), material: new Material( new Color(1, 1, 0.3), ambient: 0.1, diffuse: 0.8, specular: 0.9, shininess: 300)); var middle = new Cone( minimumY: 0, maximumY: 0.3, transform: Matrix4x4.CreateScaling(0.6, 1, 0.6).Translate(1, 0, 0), material: new Material( new Color(1, 0.9, 0.4), ambient: 0.1, diffuse: 0.8, specular: 0.9, shininess: 300)); var inner = new Cone( minimumY: 0, maximumY: 0.4, transform: Matrix4x4.CreateScaling(0.4, 1, 0.4).Translate(1, 0, 0), material: new Material( new Color(1, 0.8, 0.5), ambient: 0.1, diffuse: 0.8, specular: 0.9, shininess: 300)); var solidInner = new Cone( minimumY: 0, maximumY: 0.5, isClosed: true, transform: Matrix4x4.CreateScaling(0.2, 1, 0.2).Translate(1, 0, 0), material: new Material( new Color(1, 0.7, 0.6), ambient: 0.1, diffuse: 0.8, specular: 0.9, shininess: 300)); // Decorative Cylinders var red = new Cone( minimumY: 0, maximumY: 0.3, isClosed: true, transform: Matrix4x4.CreateScaling(0.05, 1, 0.05).Translate(0, 0, -0.75), material: new Material(Colors.Red, ambient: 0.1, diffuse: 0.9, specular: 0.9, shininess: 300)); var yellow = new Cone( minimumY: 0, maximumY: 0.3, isClosed: true, transform: Matrix4x4.CreateScaling(0.05, 1, 0.05) .Translate(0, 0, 1.5) .RotateY(-0.15) .Translate(0, 0, -2.25), material: new Material(Colors.Yellow, ambient: 0.1, diffuse: 0.9, specular: 0.9, shininess: 300)); var green = new Cone( minimumY: 0, maximumY: 0.3, isClosed: true, transform: Matrix4x4.CreateScaling(0.05, 1, 0.05) .Translate(0, 0, 1.5) .RotateY(-0.3) .Translate(0, 0, -2.25), material: new Material(Colors.Green, ambient: 0.1, diffuse: 0.9, specular: 0.9, shininess: 300)); var cyan = new Cone( minimumY: 0, maximumY: 0.3, isClosed: true, transform: Matrix4x4.CreateScaling(0.05, 1, 0.05) .Translate(0, 0, 1.5) .RotateY(-0.45) .Translate(0, 0, -2.25), material: new Material(Colors.Cyan, ambient: 0.1, diffuse: 0.9, specular: 0.9, shininess: 300)); var glass = new Cone( minimumY: 0.0001, maximumY: 0.5, isClosed: true, transform: Matrix4x4.CreateScaling(0.33, 1, 0.33).Translate(0, 0, -1.5), material: new Material( new Color(0.25, 0, 0), diffuse: 0.1, specular: 0.9, shininess: 300, reflective: 0.9, transparency: 0.9, refractiveIndex: 1.5)); // Lights, camera, action. var light = new PointLight(new Point(1, 6.9, -4.9), Colors.White); var world = new World(light, floor, blueCylinder, outer, middle, inner, solidInner, red, yellow, green, cyan, glass); var cameraTransform = Matrix4x4.CreateLookAt(new Point(8, 3.5, -9), new Point(0, 0.3, 0), Vector.UnitY); var camera = new Camera(CanvasWidth, CanvasHeight, fieldOfView: 0.314, cameraTransform); Canvas canvas = camera.Render(world, options); return(canvas); }