protected override void Render(REScene scene, Camera3D camera, Canvas canvas) { double d = 2 * camera.FocusDistance * System.Math.Tan(camera.FOV / 2); double h = d / System.Math.Sqrt(camera.Ratio * camera.Ratio + 1); double w = h * camera.Ratio; double hFOV = 2 * System.Math.Atan(w / (2 * camera.FocusDistance)); double vFOV = 2 * System.Math.Atan(h / (2 * camera.FocusDistance)); double alpha0 = -hFOV / 2; double beta0 = -vFOV / 2; double dAlpha = hFOV / canvas.Width; double dBeta = vFOV / canvas.Height; double alpha = alpha0, beta = beta0; var ray = new ColoredRay3D(); var dirZ = (float)camera.FocusDistance; for (int cy = 0; cy < canvas.Height; cy++) { var dirY = (float)(System.Math.Tan(beta) * camera.FocusDistance); for (int cx = 0; cx < canvas.Width; cx++) { var dirX = (float)(System.Math.Tan(alpha) * camera.FocusDistance); ray.Color = new PreciseColor(1.0f, 1.0f, 1.0f); ray.Start = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z - (float)camera.FocusDistance); ray.End = ray.Start + new Vector3D(dirX, dirY, dirZ); PreciseColor color = ProcessRay(ray, scene, 0); canvas[cx, cy] += color; alpha += dAlpha; } alpha = alpha0; beta += dBeta; } }
protected virtual NearestIntersection GetIntersections(ColoredRay3D ray, REScene scene) { var intersections = new NearestIntersection(); ray.End = ray.Start + (ray.End - ray.Start).Normalize(); scene.Objects.GetIntersections(ray, intersections); return intersections; }
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; }
protected virtual REScene PrepareScene(Scene3D scene, Camera3D camera) { var wrappedScene = new REScene(); var preparationContext = new RenderPreparationContext(wrappedScene); preparationContext.PushCoordinateSystem(camera.CoordinateSystem); _shapeDecorator = new Shape3DDecorator(preparationContext); scene.Shapes.AcceptVisitor(_shapeDecorator); wrappedScene.Objects.Add(_shapeDecorator.DecoratedShape); scene.Lights.AcceptVisitor(_shapeDecorator); wrappedScene.Lights.Add(_shapeDecorator.DecoratedLight); preparationContext.PopCoordinateSystem(); return wrappedScene; }
protected override void Render(REScene scene, Camera3D camera, Canvas canvas) { foreach (REBaseLight lightSource in scene.Lights) { var start = lightSource.Origin.CoordinateSystem.Position; var dir = new Vector3D( (float)(_rnd.NextDouble() * 2 - 1), (float)(_rnd.NextDouble() * 2 - 1), (float)(_rnd.NextDouble() * 2 - 1) ).Normalize(); var ray = new ColoredRay3D { Color = new PreciseColor(1, 1, 1), Start = start, End = start + dir }; ProcessRay(ray, scene, 0); } }
public RenderPreparationContext(REScene scene) { this.scene = scene; }
protected REBaseLight(Light3D origin, REScene scene) { this.origin = origin; this.scene = scene; }
protected abstract void Render(REScene scene, Camera3D camera, Canvas canvas);
protected virtual PreciseColor GetSpecularIllumination(Intersection intersection, REScene scene) { return scene.Lights.GetSpecularIllumination(intersection); }
public REOmniLight(OmniLight3D origin, Vector3D position, REScene scene) : base(origin, scene) { omni = origin; this.position = position; }