internal static System.Drawing.Color[,] Render(int screenWidth, int screenHeight, int numSamples, Scene scene) { System.Drawing.Color[,] pixels = new System.Drawing.Color[screenWidth, screenHeight]; Camera camera = scene.Camera; F64 sx = F64.Ratio(1, 2 * screenWidth); F64 ox = F64.Half * F64.FromInt(screenWidth); F64 sy = -F64.Ratio(1, 2 * screenHeight); F64 oy = F64.Half * F64.FromInt(screenHeight); F32 ooNumSamples = F32.Ratio(1, numSamples); //for (int y = 0; y < screenHeight; y++) Parallel.For(0, screenHeight, y => { Random rnd = new Random(y * 29827341 + 23427343); for (int x = 0; x < screenWidth; x++) { Color accum = Color.Black; for (int i = 0; i < numSamples; i++) { // rx, ry == random offset in range [-0.5, 0.5] F64 rx = F64.FromRaw(rnd.Next()) * 2 - F64.Half; F64 ry = F64.FromRaw(rnd.Next()) * 2 - F64.Half; F64 xx = (F64.FromInt(x) + rx - ox) * sx; F64 yy = (F64.FromInt(y) + ry - oy) * sy; F64Vec3 rayDir = F64Vec3.Normalize(camera.Forward + xx * camera.Right + yy * camera.Up); Color color = TraceRay(new Ray(camera.Pos, rayDir), scene, 0); accum += color; } pixels[x, y] = (ooNumSamples * accum).ToDrawingColor(); } }); return(pixels); }
private static Color Shade(Ray ray, ISect isect, Scene scene, int depth) { var pos = isect.Pos; var normal = isect.Normal; var reflectDir = ray.Dir - 2 * F64Vec3.Dot(normal, ray.Dir) * normal; Color ret = Color.Black; Material material = isect.Material; ret += GetNaturalColor(material, pos, normal, reflectDir, scene); if (depth >= MaxDepth) { return(ret + new Color(F32.Half, F32.Half, F32.Half)); } return(ret + GetReflectionColor(material, pos + F64.Ratio(1, 1000) * reflectDir, normal, reflectDir, scene, depth)); }