protected virtual NearestIntersection GetIntersections(ColoredRay3D ray) { NearestIntersection intersections = new NearestIntersection(); ray.End = ray.Start + (ray.End - ray.Start).Normalize(); scene.Objects.GetIntersections(ray, intersections); return intersections; }
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 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(); }
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 override void GetIntersections(ColoredRay3D ray, NearestIntersection intersections) { rectangle.GetIntersections(ray, intersections); }
public override void GetIntersections(ColoredRay3D ray, NearestIntersection intersections) { RayEngineMath.GetIntersections(ray, this, intersections); }
//TODO: Hide ray from params. Use its parameters instead. public abstract void GetIntersections(ColoredRay3D ray, NearestIntersection intersections);