public void RayTrace(Camera camera, StringBuilder[,] logs) { int width = myBitmap.Width; int height = myBitmap.Height; var forward = camera.Right ^ camera.Top; var xAngle = width > height ? camera.ViewAngle : camera.ViewAngle * width / height; var yAngle = height > width ? camera.ViewAngle : camera.ViewAngle * height / width; for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { lock (LockObject) { Vector color = Vector.Zero; for (int ii = 0; ii < AntiAliasPasses; ii++) for (int jj = 0; jj < AntiAliasPasses; jj++) { var x = (double) (j * AntiAliasPasses + jj) / (width * AntiAliasPasses) - 0.5; var y = (double) (i * AntiAliasPasses + ii) / (height * AntiAliasPasses) - 0.5; var direction = camera.Right * Math.Sin(x * xAngle) + camera.Top * Math.Sin(y * yAngle) + forward * (Math.Cos(x * camera.ViewAngle) + Math.Cos(y * camera.ViewAngle)); var ray = new Ray(camera.Origin, direction); myTraceDepth = 0; color = color + TraceRay(ray, logs == null ? null : logs[j, height - 1 - i]); } myBitmap.SetPixel(j, height - 1 - i, ColorUtil.ToColor((color / (AntiAliasPasses * AntiAliasPasses)))); } } }
private bool IntersectRay(Ray ray, out IShape minShape, out IntersectionData mint) { mint = new IntersectionData(ray, double.PositiveInfinity, null); minShape = null; foreach (var shape in Shapes) { var t = shape.Intersect(ray); if (t == null) continue; if (t.Value.RayPoint < mint.RayPoint) { mint = t.Value; minShape = shape; } } return minShape != null; }
public override IntersectionData? Intersect(Ray ray) { double t1; double t2; var origin = ray.Origin - myCenter; if (!MathUtil.SolveSquareEq(ray.Direction * ray.Direction, 2.0 * origin * ray.Direction, (origin * origin) - (myRadius * myRadius), out t1, out t2)) return null; if (t1 < 0 && t2 < 0) return null; double t; if (t1 <= 0 && t2 > 0) t = t2; else if (t1 > 0 && t2 <= 0) t = t1; else t = Math.Min(t1, t2); return new IntersectionData(ray, t, (ray[t] - Center).Normalize()); }
private Vector TraceRay(Ray ray, StringBuilder log) { myTraceDepth++; if (myTraceDepth > 5) return Vector.Zero; if (log != null) log.AppendLine(string.Format("Incoming ray: {0}", ray)); IShape shape; IntersectionData intersectionData; if (!IntersectRay(ray, out shape, out intersectionData)) return Vector.Zero; var intersectionPoint = ray[intersectionData.RayPoint] + intersectionData.Normal.Normalize(MathUtil.Epsilon); if (log != null) { log.AppendLine(string.Format("Intersection: {0}", intersectionPoint)); log.AppendLine(string.Format("Normal: {0}", intersectionData.Normal)); log.AppendLine(string.Format("Shape: {0}", shape.Name)); } var texCoords = shape.GetTextureCoords(intersectionPoint); var color = shape.Texture.GetColor(texCoords.X, texCoords.Y) * shape.Ambient; foreach (var light in Lights) { var lightDirection = light.Point - intersectionPoint; IShape lightShape; IntersectionData lightIntersectionData; var rayToLight = new Ray(intersectionPoint, lightDirection); if (log != null) log.AppendLine(string.Format("Ray to light: {0}", rayToLight)); if (IntersectRay(rayToLight, out lightShape, out lightIntersectionData)) if (lightIntersectionData.RayPoint < 1) continue; var specular = ray.Direction & Reflect(lightDirection.Normalize(), intersectionData.Normal); if (specular > 0) specular = Math.Pow(specular, shape.Shineness) * shape.Specular; else specular = 0; color = color + (light.Color * light.Luminosity * shape.Diffuse * MathUtil.Cast(lightDirection & intersectionData.Normal)) + (light.Color * specular); } var reflectedDirection = Reflect(ray.Direction.Normalize(), intersectionData.Normal); var reflectedColor = TraceRay(new Ray(intersectionPoint, reflectedDirection), log); color = color + shape.Reflect * reflectedColor; return color.Cast(1); }
public override IntersectionData? Intersect(Ray ray) { var t = (-myDistance - (ray.Origin * myNormal)) / (ray.Direction * myNormal); if (t < 0) return null; return new IntersectionData(ray, t, myNormal); }
public abstract IntersectionData? Intersect(Ray ray);