public void InShadowWhenAnObjectIsBetweenLightAndPoint() { var w = World.Default(); var p = new Point(10, -10, 10); PhongShading.IsShadowed(w, p, w.Lights[0].Position).Should().BeTrue(); }
public void NotInShadowWhenObjectIsBehindPoint() { var w = World.Default(); var p = new Point(-2, 2, -2); PhongShading.IsShadowed(w, p, w.Lights[0].Position).Should().BeFalse(); }
public void NotInShadowWhenNothingBetweenLightAndPoint() { var w = World.Default(); var p = new Point(0, 10, 0); PhongShading.IsShadowed(w, p, w.Lights[0].Position).Should().BeFalse(); }
public void ColorWhenRayHits() { var w = World.Default(); var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var c = PhongShading.ColorAt(w, r); c.Should().Be(new Color(0.38066f, 0.47583f, 0.2855f)); }
public void ColorWhenRayMissesIsBlack() { var w = World.Default(); var r = new Ray(new Point(0, 0, -5), new Vector(0, 1, 0)); var c = PhongShading.ColorAt(w, r); c.Should().Be(new Color(0, 0, 0)); }
public void ReflectanceIsSignificantAtSmallViewAngles() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0.99f, -2f), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(1.8589f, s)); var comps = new IntersectionInfo(xs[0], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().BeApproximately(0.48873f, 0.0001f); }
public void RefractedColorOfOpaqueSurfaceIsBlack() { var w = World.Default(); var s = w.Objects[0]; var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(4f, s), new Intersection(6f, s)); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.RefractedColor(w, comps, 5).Should().Be(Colors.Black); }
public void SchlickApproximationForTotalInternalReflectionIsOne() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0, MathF.Sqrt(2f) / 2f), new Vector(0, 1, 0)); var xs = Intersections.Create(new Intersection(-MathF.Sqrt(2f) / 2f, s), new Intersection(MathF.Sqrt(2f) / 2f, s)); var comps = new IntersectionInfo(xs[1], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().Be(1f); }
public void ReflectanceIsSmallAtPerpendicularViewAngles() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0, 0), new Vector(0, 1, 0)); var xs = Intersections.Create(new Intersection(-1f, s), new Intersection(1f, s)); var comps = new IntersectionInfo(xs[1], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().BeApproximately(0.04f, 0.0001f); }
public void ColorWithIntersectionBehind() { var w = World.Default(); w.Objects[0].Material.Ambient = 1f; w.Objects[1].Material.Ambient = 1f; var r = new Ray(new Point(0, 0, 0.75f), new Vector(0, 0, -1)); var c = PhongShading.ColorAt(w, r); c.Should().Be(w.Objects[1].Material.Texture.LocalColorAt(Point.Zero)); }
public void ShadingOutsideIntersection() { var w = World.Default(); var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var shape = w.Objects[0]; var i = new Intersection(4f, shape); var comps = new IntersectionInfo(i, r); var c = PhongShading.HitColor(w, comps); c.Should().Be(new Color(0.38066f, 0.47583f, 0.2855f)); }
public void LightOnSurfaceInShadow() { var s = new Sphere(); var m = new Material(); var position = Point.Zero; var eyeV = new Vector(0, 0, -1f); var normal = new Normal(0, 0, -1); var light = new PointLight(new Point(0, 0, -10), new Color(1f, 1f, 1f)); var result = PhongShading.Lighting(m, s, light, position, eyeV, normal, 0); result.Should().BeEquivalentTo(new Color(0.1f, 0.1f, 0.1f)); }
public void ReflectedColorForNonReflectiveMaterialIsBlack() { var w = World.Default(); var r = new Ray(new Point(0, 0, 0), new Vector(0, 0, 1)); var shape = w.Objects[1]; shape.Material.Ambient = 1f; var i = new Intersection(1, shape); var comps = new IntersectionInfo(i, r); PhongShading.ReflectedColor(w, comps).Should().Be(Colors.Black); }
public void FullReflectionOfLightOffset45Deg() { var s = new Sphere(); var m = new Material(); var position = Point.Zero; var eyeV = new Vector(0, -MathF.Sqrt(2) / 2, -MathF.Sqrt(2) / 2); var normal = new Normal(0, 0, -1); var light = new PointLight(new Point(0, 10, -10), new Color(1f, 1f, 1f)); var result = PhongShading.Lighting(m, s, light, position, eyeV, normal, 1); result.Should().BeEquivalentTo(new Color(1.6364f, 1.6364f, 1.6364f)); }
public void LightIntensityAtPoint() { var w = World.Default(); var light = w.Lights[0]; PhongShading.IntensityAt(w, new Point(0, 1.0001f, 0), light).Should().BeApproximately(1.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(-1.0001f, 0, 0), light).Should().BeApproximately(1.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(0, 0, -1.0001f), light).Should().BeApproximately(1.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(0, 0, 1.0001f), light).Should().BeApproximately(0.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(1.0001f, 0, 0), light).Should().BeApproximately(0.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(0, -1.0001f, 0), light).Should().BeApproximately(0.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(0, 0, 0), light).Should().BeApproximately(0.0f, 0.0001f); }
public void ShadingInsideIntersection() { var w = World.Default(); w.SetLights(new PointLight(new Point(0, 0.25f, 0), new Color(1f, 1f, 1f))); var r = new Ray(new Point(0, 0, 0), new Vector(0, 0, 1)); var shape = w.Objects[1]; var i = new Intersection(0.5f, shape); var comps = new IntersectionInfo(i, r); var c = PhongShading.HitColor(w, comps); c.Should().Be(new Color(0.90482f, 0.90482f, 0.90482f)); }
public void RefractedColorIsBlackIfRemainingBouncesIsZero() { var w = World.Default(); var s = w.Objects[0]; s.Material.Transparency = 1.0f; s.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(4f, s), new Intersection(6f, s)); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.RefractedColor(w, comps, 0).Should().Be(Colors.Black); }
public void CalculateAreaLightIntensityWithJitter() { var w = World.Default(); var corner = new Point(-0.5f, -0.5f, -5); var v1 = new Vector(1, 0, 0); var v2 = new Vector(0, 1, 0); var light = new AreaLight(corner, v1, 2, v2, 2, Colors.White, new Sequence(0.7f, 0.3f, 0.9f, 0.1f, 0.5f)); PhongShading.IntensityAt(w, new Point(0, 0, 2), light).Should().BeApproximately(0.0f, 0.0001f); PhongShading.IntensityAt(w, new Point(1, -1, 2), light).Should().BeApproximately(0.75f, 0.0001f); PhongShading.IntensityAt(w, new Point(1.5f, 0, 2), light).Should().BeApproximately(0.75f, 0.0001f); PhongShading.IntensityAt(w, new Point(1.25f, 1.25f, 3), light).Should().BeApproximately(0.75f, 0.0001f); PhongShading.IntensityAt(w, new Point(0f, 0f, -2), light).Should().BeApproximately(1.0f, 0.0001f); }
public void LightOnSurfaceInPartialShadow() { var s = new Sphere(); var m = new Material { Ambient = 0.1f, Diffuse = 0.9f, Specular = 0 }; var position = new Point(0, 0, -1); var eyeV = new Vector(0, 0, -1f); var normal = new Normal(0, 0, -1); var light = new PointLight(new Point(0, 0, -10), new Color(1f, 1f, 1f)); var result = PhongShading.Lighting(m, s, light, position, eyeV, normal, 0.5f); result.Should().BeEquivalentTo(new Color(0.55f, 0.55f, 0.55f)); }
public void ReflectedColorForReflectiveMaterialIsNotBlack() { var w = World.Default(); var shape = new Plane(); shape.SetMaterial(new Material { Reflective = 0.5f }); shape.SetTransform(Transform.Translate(0, -1, 0)); w.AddObject(shape); var r = new Ray(new Point(0, 0, -3), new Vector(0, -MathF.Sqrt(2f) / 2f, MathF.Sqrt(2f) / 2f)); var i = new Intersection(MathF.Sqrt(2f), shape); var comps = new IntersectionInfo(i, r); PhongShading.ReflectedColor(w, comps).Should().Be(new Color(0.19041f, 0.2380f, 0.14281f)); }
public void ReflectedColorIsBlackIfRemainingBouncesIsZero() { var w = World.Default(); var shape = new Plane(); shape.SetMaterial(new Material { Reflective = 0.5f }); shape.SetTransform(Transform.Translate(0, -1, 0)); w.AddObject(shape); var r = new Ray(new Point(0, 0, -3), new Vector(0, -MathF.Sqrt(2f) / 2f, MathF.Sqrt(2f) / 2f)); var i = new Intersection(MathF.Sqrt(2f), shape); var comps = new IntersectionInfo(i, r); PhongShading.ReflectedColor(w, comps, 0).Should().Be(Colors.Black); }
public void HitColorIncludeReflectedColor() { var w = World.Default(); var shape = new Plane(); shape.SetMaterial(new Material { Reflective = 0.5f }); shape.SetTransform(Transform.Translate(0, -1, 0)); w.AddObject(shape); var r = new Ray(new Point(0, 0, -3), new Vector(0, -MathF.Sqrt(2f) / 2f, MathF.Sqrt(2f) / 2f)); var i = new Intersection(MathF.Sqrt(2f), shape); var comps = new IntersectionInfo(i, r); PhongShading.HitColor(w, comps).Should().Be(new Color(0.87677f, 0.92436f, 0.82918f)); }
public void RefractedColorIsBlackForTotalInternalRefraction() { var w = World.Default(); var s = w.Objects[0]; s.Material.Transparency = 1.0f; s.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, MathF.Sqrt(2f) / 2f), new Vector(0, 1, 0)); var xs = Intersections.Create( new Intersection(-MathF.Sqrt(2f) / 2f, s), new Intersection(MathF.Sqrt(2f) / 2f, s)); // Inside sphere so look at second intersection. var comps = new IntersectionInfo(xs[1], r, xs); PhongShading.RefractedColor(w, comps, 5).Should().Be(Colors.Black); }
public void LightingWithPatternApplied() { var s = new Sphere(); var m = new Material { Texture = new StripeTexture(Colors.White, Colors.Black), Ambient = 1f, Diffuse = 0f, Specular = 0f }; var eye = new Vector(0, 0, -1); var normal = new Normal(0, 0, -1); var light = new PointLight(new Point(0, 0, -10), Colors.White); var c1 = PhongShading.Lighting(m, s, light, new Point(0.9f, 0, 0), eye, normal, 1); var c2 = PhongShading.Lighting(m, s, light, new Point(1.1f, 0, 0), eye, normal, 1); c1.Should().Be(Colors.White); c2.Should().Be(Colors.Black); }
public void RaycastTest() { const int canvasPixels = 100; var canvas = new Canvas(canvasPixels, canvasPixels); var s = new Sphere { Material = { Texture = new SolidColor(new Color(0.4f, 0.2f, 1)) } }; var light = new PointLight(new Point(-10, 10, -10), new Color(1f, 1f, 1f)); //var t = Transforms.Shear(0.1f, 0, 0, 0, 0, 0).Scale(0.9f, 1f, 1f); //s.SetTransform(t); var rayOrigin = new Point(0f, 0f, -5f); const float wallZ = 10f; const float wallSize = 7.0f; const float pixelSize = wallSize / canvasPixels; const float half = wallSize / 2; for (var y = 0; y < canvasPixels; y++) { var worldY = half - pixelSize * y; for (var x = 0; x < canvasPixels; x++) { var worldX = -half + pixelSize * x; var position = new Point(worldX, worldY, wallZ); var r = new Ray(rayOrigin, (position - rayOrigin).Normalize()); var xs = s.Intersects(r); var hit = xs.Hit(); if (!hit.HasValue) { continue; } var point = r.Position(hit.Value.T); var shape = hit.Value.Geometry; var normal = shape.NormalAt(point, hit.Value); var eye = -r.Direction; var color = PhongShading.Lighting(shape.Material, shape, light, point, eye, normal, 1); canvas.WritePixel(color, x, y); } } PPM.ToFile(canvas, Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "raycast"); }
public void HandleParallelReflectiveSurfaces() { var w = new World(); w.SetLights(new PointLight(new Point(0, 0, 0), Colors.White)); var lower = new Plane { Material = { Reflective = 1f } }; lower.SetTransform(Transform.Translate(0, -1, 0)); var upper = new Plane { Material = { Reflective = 1f } }; upper.SetTransform(Transform.Translate(0, 1, 0)); w.SetObjects(lower, upper); var r = new Ray(new Point(0, 0, 0), new Vector(0, 1, 0)); // Test to ensure an infinite loop is not hit. PhongShading.ColorAt(w, r).Should().NotBe(new Color(1, 0, 0)); }
public void CalculateLightingWithAreaLight() { var corner = new Point(-0.5f, -0.5f, -5); var v1 = new Vector(1, 0, 0); var v2 = new Vector(0, 1, 0); var light = new AreaLight(corner, v1, 2, v2, 2, Colors.White); var s = new Sphere { Material = { Ambient = 0.1f, Diffuse = 0.9f, Specular = 0f, Texture = new SolidColor(Colors.White) } }; var eye = new Point(0, 0, -5); var pt = new Point(0, 0, -1); var eyeV = (eye - pt).Normalize(); var normal = new Normal(pt.X, pt.Y, pt.Z); var r = PhongShading.Lighting(s.Material, s, light, pt, eyeV, normal, 1.0f); r.Should().Be(new Color(0.9965f, 0.9965f, 0.9965f)); pt = new Point(0, 0.7071f, -0.7071f); eyeV = (eye - pt).Normalize(); normal = new Normal(pt.X, pt.Y, pt.Z); r = PhongShading.Lighting(s.Material, s, light, pt, eyeV, normal, 1.0f); r.Should().Be(new Color(0.6232f, 0.6232f, 0.6232f)); }
public void RefractsRayWhenHitsTransparentSurface() { var w = World.Default(); var a = w.Objects[0]; a.Material.Ambient = 1.0f; a.Material.Texture = new TestTexture(); var b = w.Objects[1]; b.Material.Transparency = 1.0f; b.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, 0.1f), new Vector(0, 1, 0)); var xs = Intersections.Create( new Intersection(-0.9899f, a), new Intersection(-0.4899f, b), new Intersection(0.4899f, b), new Intersection(0.9899f, a)); var comps = new IntersectionInfo(xs[2], r, xs); var c = PhongShading.RefractedColor(w, comps, 5); c.Red.Should().BeApproximately(0f, 0.001f); c.Green.Should().BeApproximately(0.99888f, 0.001f); c.Blue.Should().BeApproximately(0.04725f, 0.001f); }
public void HitColorIncludesFresnelEffectOnReflectiveTransparentSurface() { var w = World.Default(); var floor = new Plane { Material = { Transparency = 0.5f, Reflective = 0.5f, RefractiveIndex = 1.5f } }; floor.SetTransform(Transform.Translate(0, -1, 0)); w.AddObject(floor); var ball = new Sphere { Material = { Texture = new SolidColor(new Color(1, 0, 0)), Ambient = 0.5f } }; ball.SetTransform(Transform.Translate(0, -3.5f, -0.5f)); w.AddObject(ball); var r = new Ray(new Point(0, 0, -3), new Vector(0, -MathF.Sqrt(2f) / 2f, MathF.Sqrt(2f) / 2f)); var i = new Intersection(MathF.Sqrt(2f), floor); var xs = Intersections.Create(i); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.HitColor(w, comps, 5).Should().Be(new Color(0.93391f, 0.69643f, 0.69243f)); }
private void DrawButton_Click(object sender, RoutedEventArgs e) { try { textureEnabled(false); if (model != null) { WriteableBitmap source = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); ModelParams modelParams = GetModelsParams(); Model modelMain = model.Clone() as Model; CoordTransformations.TransformFromWorldToView(modelMain, modelParams); if (modelMain.CheckSize(width, height)) { Color color = Color.FromRgb(byte.Parse(colorRTextBox.Text), byte.Parse(colorGTextBox.Text), byte.Parse(colorBTextBox.Text)); Vector3 lighting = new Vector3(int.Parse(lightVectorXTextBox.Text), int.Parse(lightVectorYTextBox.Text), -int.Parse(lightVectorZTextBox.Text)); if (bresenhamRadioButton.IsChecked == true) { // lab 1-2 BresenhamAlg bresenham = new BresenhamAlg(bitmap, modelMain); bresenham.DrawModel(color); } else if (plainShadingRadioButton.IsChecked == true) { // lab 3 PlaneShading shader = new PlaneShading(bitmap, modelMain, new LambertLighting(lighting)); shader.DrawModel(color); } else if (phongShadingRadioButton.IsChecked == true) { textureEnabled(true); // затенение фонга Vector3 viewVector = new Vector3(int.Parse(colorRTextBox_View.Text), int.Parse(colorGTextBox_View.Text), int.Parse(colorBTextBox_View.Text)); Vector3 koef_a = new Vector3(float.Parse(colorRTextBox_A.Text), float.Parse(colorGTextBox_A.Text), float.Parse(colorBTextBox_A.Text)); Vector3 koef_d = new Vector3(float.Parse(colorRTextBox_D.Text), float.Parse(colorGTextBox_D.Text), float.Parse(colorBTextBox_D.Text)); Vector3 koef_s = new Vector3(float.Parse(colorRTextBox_S.Text), float.Parse(colorGTextBox_S.Text), float.Parse(colorBTextBox_S.Text)); Vector3 ambientColor = new Vector3(int.Parse(colorRTextBox_Ambient.Text), int.Parse(colorGTextBox_Ambient.Text), int.Parse(colorBTextBox_Ambient.Text)); Vector3 reflectionColor = new Vector3(int.Parse(colorRTextBox_Reflection.Text), int.Parse(colorGTextBox_Reflecion.Text), int.Parse(colorBTextBox_Reflection.Text)); float shiness = float.Parse(shinessBox.Text); bool d = false, n = false, s = false; if ((diffuseCheckBox != null && (bool)diffuseCheckBox.IsChecked)) { d = true; } if ((normalCheckBox != null && (bool)normalCheckBox.IsChecked)) { n = true; } if ((mirrorCheckBox != null && (bool)mirrorCheckBox.IsChecked)) { s = true; } var light = new PhongLighting(lighting, viewVector, koef_a, koef_d, koef_s, ambientColor, reflectionColor, shiness, d, n, s); //var light = new LambertLighting(lighting); PhongShading shader = new PhongShading(bitmap, modelMain, light, d, n, s); shader.DrawModel(color); } screenPictureBox.Source = bitmap.Source; } } else { MessageBox.Show("Load an object"); } } catch (Exception ex) { MessageBox.Show("Произошла ошибка! " + ex); } }