private RGBColor SampleLight(Vector2 uv, Scene scene, Vector2 lightSampleDirection, int maxRecursionDepth = 16) { var ray = new Ray(uv, lightSampleDirection); (var t, var shape) = Raymarcher.March(ray); if (t < Raymarcher.MinMarchDistance) { return(shape.Material.DiffuseColor); } if (t < Raymarcher.MaxMarchDistance) { if (shape.Material.Reflectivity > 0 && maxRecursionDepth > 0) { var p = ray.GetPoint(t); var normal = scene.NormalAtPoint(p); var reflectedRay = Vector2.Reflect(lightSampleDirection, normal); var light = shape.Material.Intensity * shape.Material.EmissiveColor; var reflected = SampleLight(p + 0.001 * reflectedRay, scene, reflectedRay, maxRecursionDepth - 1); return((1.0 - shape.Material.Reflectivity) * light + shape.Material.Reflectivity * reflected); } // TODO: Refraction return(shape.Material.Intensity * shape.Material.EmissiveColor); } else if (t > Raymarcher.MaxMarchDistance) { return(scene.AmbientColor); } return(RGBColor.Black); }
public void Render(Camera camera, Scene scene, string outputFileName) { WriteRenderInfo(camera); var nmd = new NormalMapDebugger(camera, scene); SceneDistanceBuffer = new SceneDistanceBuffer(camera, scene); SceneDistanceBuffer.SaveToFile(); Status = new RenderStatus(camera.DevicePixelHeight); Raymarcher = new Raymarcher(scene, SceneDistanceBuffer); var nCores = Environment.ProcessorCount; var yLines = Enumerable.Range(0, camera.DevicePixelHeight).ToList(); Parallel.ForEach(yLines, (y) => RenderRow(camera, scene, y)); Console.WriteLine(); camera.SaveToFile(outputFileName); }