private void CalculateRays() { while (true) { Parallel.For(0, 1000, (_) => { var x = ThreadSafeRandom.NextDouble() - 0.5; var y = ThreadSafeRandom.NextDouble() - 0.5; var pixel = Model.Eye + x * Right + y * Up; var source = Model.Eye - Forward * FocalLength; var ray = new Ray(source, pixel - source); var result = ray.March(Model.Field, 0.01, 200.0, Model.Fog); displayMethod.AddPoint(new ColoredPoint(result.Color, x, -y)); }); } }
public SampleResult March(DistanceField field, double minimum, double maximum, Vec3 fog) { SampleResult result = field.Sample(CurrentPosition); while (true) { if (result.Distance < minimum) { break; } if (DistanceTraveled > maximum) { DistanceTraveled = maximum; break; } CurrentPosition = CurrentPosition + Direction * result.Distance; DistanceTraveled += result.Distance; result = field.Sample(CurrentPosition); } var bouncedColor = Vec3.Zero; if (result.Source) { bouncedColor = result.Color; } else if (DistanceTraveled < maximum) { var colorSum = Vec3.Zero; Vec3 target = result.Normal + Vec3.Random(); // Linearly interpolate between the perfect reflection and the scattered normal. if (ThreadSafeRandom.NextDouble() < result.Reflectance) { var reflectionTarget = Direction - 2 * result.Normal * result.Normal.Dot(Direction); target = reflectionTarget * (1 - result.Roughness) + target * result.Roughness; } var ray = new Ray(CurrentPosition + result.Normal * minimum * 2, target); var reflectionResult = ray.March(field, minimum, maximum - DistanceTraveled, fog); var rAmount = Utils.Interpolate(result.Color.X, 1, result.Reflectance); var gAmount = Utils.Interpolate(result.Color.Y, 1, result.Reflectance); var bAmount = Utils.Interpolate(result.Color.Z, 1, result.Reflectance); bouncedColor = new Vec3( reflectionResult.Color.X * rAmount * (1 - result.Absorbance), reflectionResult.Color.Y * gAmount * (1 - result.Absorbance), reflectionResult.Color.Z * bAmount * (1 - result.Absorbance) ); } else { bouncedColor = new Vec3(1.0, 0.0, 0.0); } var fogAmount = DistanceTraveled / maximum; if (maximum == 0) { fogAmount = 1; } result.Color = Utils.Interpolate(bouncedColor, fog, fogAmount); return(result); }