/// <summary> /// Constructs an intersection /// </summary> /// <param name="point">The point at which the intersection occurred</param> /// <param name="normal">The normal direction at which the intersection occurred</param> /// <param name="impactDirection">The direction the ray was traveling on impact</param> /// <param name="obj">The object that was intersected</param> /// <param name="color">The object's raw color at the intersection point</param> /// <param name="distance">The distance from the ray's origin that the intersection occurred</param> public Intersection(Vector3 point, Vector3 normal, Vector3 impactDirection, DrawableSceneObject obj, Color color, float distance) { this.Point = point; this.Normal = normal; this.ImpactDirection = impactDirection; this.ObjectHit = obj; this.Color = color; this.Distance = distance; }
public Color32Argb(Color color) { color = color.Limited; A = (byte)(255 * color.A); R = (byte)(255 * color.R); G = (byte)(255 * color.G); B = (byte)(255 * color.B); }
/// <summary> /// Returns a BGRA32 integer representation of the color /// </summary> /// <param name="color">The color object to convert</param> /// <returns>An integer value whose 4 bytes each represent a single BGRA component value from 0-255</returns> public static int ToBGRA32(Color color) { byte r = (byte)(255 * color.R); byte g = (byte)(255 * color.G); byte b = (byte)(255 * color.B); byte a = (byte)(255 * color.A); return (r << 16) | (g << 8) | (b << 0) | (a << 24); }
/// <summary> /// Linearly interpolates from one color to another based on t. /// </summary> /// <param name="from">The first color value</param> /// <param name="to">The second color value</param> /// <param name="t">The weight value. At t = 0, "from" is returned, at t = 1, "to" is returned.</param> /// <returns></returns> public static Color Lerp(Color from, Color to, float t) { t = Util.Clamp(t, 0f, 1f); return from * (1 - t) + to * t; }
/// <summary> /// Returns a new color whose components are the average of the components of first and second /// </summary> public static Color Average(Color first, Color second) { return new Color((first.backingVector + second.backingVector) * .5f); }
public Tuple <Bitmap, int, RayTracer.RayTracer, int, DateTime> RayTraceRows(Scene scene, Rectangle viewport, int startRow, int numberOfRowsToTrace, RayTracer.RayTracer raytracer, int numberOfRange) { Console.SetCursorPosition(10, 2); Console.Write(" "); int maxsamples = (int)raytracer.AntiAliasing; RayTracer.Color [ , ] buffer = new RayTracer.Color [viewport.Width + 2, numberOfRowsToTrace + 2]; DateTime timestart = DateTime.Now; Bitmap image = new Bitmap(viewport.Width, numberOfRowsToTrace); int y = 0; for (y = startRow; y < (startRow + numberOfRowsToTrace) + 2; y++) { for (int x = 0; x < viewport.Width + 2; x++) { double yp = y * 1.0f / viewport.Height * 2 - 1; double xp = x * 1.0f / viewport.Width * 2 - 1; Ray ray = scene.Camera.GetRay(xp, yp); // this will trigger the raytracing algorithm buffer [x, y - startRow] = raytracer.CalculateColor(ray, scene); // if current line is at least 2 lines into the scan if ((x > 1) && (y > startRow + 1)) { if (raytracer.AntiAliasing != AntiAliasing.None) { RayTracer.Color avg = (buffer [x - 2, y - startRow - 2] + buffer [x - 1, y - startRow - 2] + buffer [x, y - startRow - 2] + buffer [x - 2, y - startRow - 1] + buffer [x - 1, y - startRow - 1] + buffer [x, y - startRow - 1] + buffer [x - 2, y - startRow] + buffer [x - 1, y - startRow] + buffer [x, y - startRow]) / 9; if (raytracer.AntiAliasing == AntiAliasing.Quick) { // this basically implements a simple mean filter // it quick but not very accurate buffer [x - 1, y - startRow - 1] = avg; } else { // use a more accurate antialasing method (MonteCarlo implementation) // this will fire multiple rays per pixel if (avg.Distance(buffer [x - 1, y - startRow - 1]) > 0.18) // 0.18 is a treshold for detailed aliasing { for (int i = 0; i < maxsamples; i++) { // get some 'random' samples double rx = Math.Sign(i % 4 - 1.5) * (raytracer.IntNoise(x + y * viewport.Width * maxsamples * 2 + i) + 1) / 4; // interval <-0.5, 0.5> double ry = Math.Sign(i % 2 - 0.5) * (raytracer.IntNoise(x + y * viewport.Width * maxsamples * 2 + 1 + i) + 1) / 4; // interval <-0.5, 0.5> xp = (x - 1 + rx) * 1.0f / viewport.Width * 2 - 1; yp = (y - 1 + ry) * 1.0f / viewport.Height * 2 - 1; ray = scene.Camera.GetRay(xp, yp); // execute even more ray traces, this makes detailed anti-aliasing expensive buffer [x - 1, y - startRow - 1] += raytracer.CalculateColor(ray, scene); } buffer [x - 1, y - startRow - 1] /= (maxsamples + 1); } } } image.SetPixel(x - 2, y - startRow - 2, buffer [x - 1, y - startRow - 1].ToArgb()); } } //if ( ((y - startRow) / numberOfRowsToTrace * 100) % 10 == 0 ) //{ // Console.SetCursorPosition(10, 3); // Console.Write(((y-startRow) / numberOfRowsToTrace * 100) + "% "); //} } Console.SetCursorPosition(10, 3); Console.Write(100 + "% "); return(Tuple.Create <Bitmap, int, RayTracer.RayTracer, int, DateTime>(image, numberOfRange, raytracer, startRow, timestart)); }