protected virtual PreciseColor ProcessRay(ColoredRay3D ray, REScene scene, int level) { NearestIntersection intersections = GetIntersections(ray, scene); var color = new PreciseColor(); Vector3D dir = (ray.End - ray.Start).Normalize(); Intersection intersection = intersections.Get(); if (intersection != null) { if (intersection.Length > 0.05) { Material material = intersection.Shape3D.Material; color += material.DiffuseColor * material.AmbientIntensity; RayTracingOptions options = GetRayTracingOptions(intersection.Shape3D); if ((options & RayTracingOptions.Diffuse) > 0) { color += GetDiffuseIllumination(intersection, scene); } if ((options & RayTracingOptions.Speculate) > 0) { if (level < 5 && material.Shininess > 0.001) { var reflected = ray; Vector3D reflectedStart = ray.Start + dir * intersection.Length; Vector3D reflectedEnd = reflectedStart + Math3D.GetReflectedVector(dir, intersection.Normal); reflected.Start = reflectedStart; reflected.End = reflectedEnd; color += ProcessRay(reflected, scene, level + 1) * material.Shininess; } } } } return color; }
public override PreciseColor GetDiffuseIllumination(Intersection intersection) { Material material = intersection.Shape3D.Material; Vector3D dir = position - intersection.Point; float distance = dir.Length; var ray = new ColoredRay3D { Start = intersection.Point, End = position }; NearestIntersection intersections = GetIntersections(ray); bool shadowed = false; Intersection obstacle = intersections.Get(); if (obstacle != null && obstacle.Length > 0.05 && obstacle.Length < distance) { shadowed = true; } if (!shadowed) { var diffuseColor = new PreciseColor(omni.Color.Red * material.DiffuseColor.Red, omni.Color.Green * material.DiffuseColor.Green, omni.Color.Blue * material.DiffuseColor.Blue); float diffuseIntensity = omni.Power * (1 - material.Shininess) * System.Math.Abs(Vector3D.Scalar(dir.Normalize(), intersection.Normal)); diffuseIntensity /= dir.Length * dir.Length; Vector3D reflected = Math3D.GetReflectedVector((intersection.Point - position).Normalize(), intersection.Normal); float cosTeta = Vector3D.Scalar(reflected, (intersection.Ray.Start - intersection.Ray.End).Normalize()); float specularIntensity = cosTeta < 0 ? 0 : omni.Power * material.Shininess * (float)System.Math.Pow(cosTeta, 200); if (intersection.Shape3D is RESphere) { specularIntensity /= material.Shininess; } specularIntensity *= 0.05f; return diffuseColor * diffuseIntensity + material.SpecularColor * specularIntensity; } return new PreciseColor(); }
public void Clear() { _points = new PreciseColor[_height, _width]; for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { _points[y, x] = new PreciseColor(); } } }
public static Canvas FromImage(Bitmap img) { var res = new Canvas(img.Width, img.Height); for (var y = 0; y < res.Height; y++) { for (var x = 0; x < res.Width; x++) { var clr = img.GetPixel(x, y); res[x, y] = new PreciseColor(clr); } } return res; }
public bool Equals(PreciseColor other) { return (_red == other._red) && (_green == other._green) && (_blue == other._blue); }
private void Form1_Load(object sender, EventArgs e) { _scene = new Scene3D(); _scene = new VrmlToG3DConverter().Convert(@"D:\dev\graph3d\Graph3D.Vrml.Test\Ant.wrl"); _scene.Shapes.First().CoordinateSystem.Translate(new Vector3D(-0.2f, 0.3f, 0.2f)).Scale(2, 2, 2).RotateV(0.2f).RotateU(0.1f).Translate(new Vector3D(0, 0, -0.2f)); PreciseColor color = new PreciseColor(0.6f, 0.3f, 0.3f) * 0.8f; const float shininess = 0; var b = new Box3D { Material = { DiffuseColor = color, Shininess = shininess }, Width = 40, Height = 40, Depth = 120 }; _scene.Shapes.Add(b); _scene.Shapes.Add(new Sphere3D { CoordinateSystem = { Position = new Vector3D(0, 14, -2) }, Radius = 6.0f, Material = { DiffuseColor = new PreciseColor(0.0f, 0.1f, 0.0f) * 2.99f, AmbientIntensity = 0.9f, Shininess = 0.1f } }); _scene.Shapes.Add(new Sphere3D { CoordinateSystem = { Position = new Vector3D(9, 14, -2) }, Radius = 6.0f, Material = { DiffuseColor = new PreciseColor(0.0f, 0.0f, 1.0f) * 0.19f, AmbientIntensity = 0.95f, Shininess = 0.05f } }); //_scene.Shapes.Add(new Box3D { // CoordinateSystem = { Position = new Vector3D(3, 14, -6) }, // Width = 4, // Height = 4, // Depth = 4, // Material = { // DiffuseColor = new PreciseColor(0.0f, 0.0f, 1.0f) * 0.50f, // AmbientIntensity = 0.2f, // Shininess = 0.1f // } //}); const int omniCount = 5; for (int i = 0; i < omniCount; i++) { float angle = 2 * (float)System.Math.PI * i / omniCount; const float radius = 16; float x = 0 + radius * (float)System.Math.Cos(angle); float y = -19.5f; float z = -7 + radius * (float)System.Math.Sin(angle); _scene.Lights.Add(new OmniLight3D { Position = new Vector3D(x, y, z), Color = new PreciseColor(1.0f, 1.0f, 1.0f), Power = 1500.0f / omniCount }); } }
public void AddTest() { var a = new PreciseColor(1, 2, 3); var b = new PreciseColor(-2, -4, -6); var c = a + b; Assert.AreEqual(new PreciseColor(-1, -2, -3), c); }