//public Light Lighting { get; private set; } public FullScene() { // Define the camera var camera = new PerspectiveCamera(); camera.Position = new Point3D(0, .25, 10); camera.LookDirection = new Vector3D(0, 0, -1); //camera.LookDirection = new Vector3D(0, -.05, -1); camera.UpDirection = new Vector3D(0, 1, 0); camera.FieldOfView = 60; //var camera = new OrthographicCamera(); //camera.Position = new Point3D(0, 0, 85); //camera.LookDirection = new Vector3D(0, -.05, -4); //camera.NearPlaneDistance = 0; //camera.FarPlaneDistance = 100; ColorConverter conv = new ColorConverter(); var color = (Color)conv.ConvertFrom("#ffffff"); //var ambient = new AmbientLight(color); var pos = new Point3D(0, 10, 10); var spotlight = new SpotLight(); spotlight.Color = color; spotlight.Position = pos; spotlight.InnerConeAngle = 180; spotlight.OuterConeAngle = 90; spotlight.Direction = new Vector3D(pos.X * -1, pos.Y * -1, pos.Z * -1); // Define a lighting model // Collect the components this.modelGroup = new Model3DGroup(); this.modelGroup.Children.Add(ambientLight); this.modelGroup.Children.Add(spotlight); ModelVisual3D visual = new ModelVisual3D(); visual.Content = this.modelGroup; Viewport3D viewport = new Viewport3D(); viewport.Children.Add(visual); viewport.Camera = camera; this.Viewport = viewport; }
/* * Returns the colour that would be seen for a specific ray trace */ public Colour RayTrace(WorldSpace world, Vector3 viewVector, Vector3 intersect, Triangle triangle, int reflectiveBounces) { RayHit reflectHit; Colour diffuse; Vector3 lightRay; float lightCos; if (world.light.GetType() == typeof(DirectionalLight)) { //Directional lighting DirectionalLight worldLight = (DirectionalLight)world.light; lightRay = Vector3.Unit(Vector3.Multiply(worldLight.lightVec, -1)); lightCos = Math.Abs(Vector3.DotProduct(lightRay, triangle.normal)); reflectHit = GetRayHit(world, intersect, lightRay, triangle); diffuse = Colour.Combine(triangle.material.diffuse, world.light.colour, world.light.brightness * lightCos * triangle.material.diffuseVal); } else if (world.light.GetType() == typeof(SpotLight)) { //Spot lighting SpotLight worldLight = (SpotLight)world.light; Vector3 spotVector = Vector3.Unit(Vector3.Multiply(worldLight.lightVec, -1)); lightRay = Vector3.Subtract(world.light.origin, intersect); float lightDistance = lightRay.Magnitude(); lightRay = Vector3.Unit(lightRay); lightCos = Math.Abs(Vector3.DotProduct(lightRay, triangle.normal)); if (Vector3.DotProduct(spotVector, lightRay) >= Math.Cos(worldLight.spotAngle)) { reflectHit = GetRayHit(world, intersect, lightRay, triangle); diffuse = Colour.Combine(triangle.material.diffuse, world.light.colour, world.light.brightness * lightCos * triangle.material.diffuseVal / (lightDistance * lightDistance)); } else { reflectHit = new RayHit(); reflectHit.hit = true; diffuse = new Colour(ColourList.BLACK); } } else { //Point lighting lightRay = Vector3.Subtract(world.light.origin, intersect); float lightDistance = lightRay.Magnitude(); lightRay = Vector3.Unit(lightRay); lightCos = Math.Abs(Vector3.DotProduct(lightRay, triangle.normal)); reflectHit = GetRayHit(world, intersect, lightRay, triangle); diffuse = Colour.Combine(triangle.material.diffuse, world.light.colour, world.light.brightness * lightCos * triangle.material.diffuseVal / (lightDistance * lightDistance)); } Colour ambient = Colour.Combine(triangle.material.diffuse, background, world.ambientBrightness); Colour reflection = new Colour(ColourList.BLACK); Colour specular = new Colour(ColourList.BLACK); if (reflectiveBounces > 0 && triangle.material.reflectivity > 0) { //Checks for recursive reflectivity Vector3 reverseVector = Vector3.Unit(Vector3.Multiply(viewVector, -1)); Vector3 reflectance = Vector3.Subtract(Vector3.Multiply(triangle.normal, 2 * Vector3.DotProduct(triangle.normal, reverseVector)), reverseVector); Vector3 lightReflectance = Vector3.Subtract(Vector3.Multiply(triangle.normal, 2 * Vector3.DotProduct(triangle.normal, lightRay)), lightRay); float specularDot = Vector3.DotProduct(lightReflectance, reverseVector); if (specularDot < 0) { specularDot = 0; } specular = Colour.Combine(triangle.material.specular, world.light.colour, triangle.material.reflectivity * (float)Math.Pow(specularDot, triangle.material.shininess)); RayHit reflectionHit = GetRayHit(world, intersect, reflectance, triangle); if (reflectionHit.hit) { float smallestDistance = reflectionHit.distances[0]; Vector3 reflectionIntersect = reflectionHit.intersects[0]; Triangle reflectionTriangle = reflectionHit.triangles[0]; for (int k = 1; k < reflectionHit.intersects.Count; k++) { if (reflectionHit.distances[k] < smallestDistance) { smallestDistance = reflectionHit.distances[k]; reflectionIntersect = reflectionHit.intersects[k]; reflectionTriangle = reflectionHit.triangles[k]; } } reflection = Colour.Add(reflection, Colour.Multiply(RayTrace(world, reflectance, reflectionIntersect, reflectionTriangle, reflectiveBounces - 1), triangle.material.reflectivity)); } } if (reflectHit.hit) { return(Colour.Add(ambient, reflection)); } else { return(Colour.Add(ambient, diffuse, reflection, specular)); } }