static void Main(string[] args) { for (var i = 0; i < 100; i++) { var num = i / 10f; var a = MathF.Sqrt(num); var b = MathHelpres.FastSqrt(num); Console.WriteLine($"{num}: {a} vs {b}"); } for (var i = 0; i < 100; i++) { var num = i / 10.0; var a = Math.Sqrt(num); var b = MathHelpres.FastSqrt(num); Console.WriteLine($"{num}: {a} vs {b}"); } //BenchmarkRunner.Run<Md5_Sha256>(); BenchmarkRunner.Run <Sqrt_FastSqrt>(); Console.ReadKey(); }
public override bool GetIntersection(Ray ray, double maxDistance, out Hit hit, out double distance) { hit = new Hit(); var delta = ray.Origin - Position; var a = Dot(ray.Direction, ray.Direction); var b = 2 * Dot(ray.Direction, delta); var c = Dot(delta, delta) - Radius * Radius; double dt = b * b - 4 * a * c; if (dt < 0) { distance = 0; return(false); } else { double D = (-b - MathHelpres.FastSqrt(dt)) / (a * 2); if (D < 0) { distance = 0; return(false); } var position = ray.Origin + ray.Direction * (float)D; var dist = Distance(position, ray.Origin); if (dist > maxDistance) { distance = dist; return(false); } hit.Position = position; hit.Normal = CalcNormal(hit.Position); hit.HitObject = this; distance = dist; return(hit.IsHitting); } }
public double FastInvSqrt64() => MathHelpres.QuakeInvSqrt(_double);
public double FastSqrt64() => MathHelpres.FastSqrt(_double);
public float FastInvSqrt32() => MathHelpres.QuakeInvSqrt(_single);
public float FastSqrt32() => MathHelpres.FastSqrt(_single);
private Color TracePath(RenderContext context, Camera camera, Ray ray, Color back, int depth = 0, Shape currentShape = null) { // Bounced enough times if (depth >= camera.MaxBounceDepth) { return(back); } var maxDistance = camera.MaxDistance; var hit = FindClosestHit(ray, maxDistance, currentShape); if (!hit.IsHitting) { return(back); // Nothing was hit } var material = hit.HitObject.Material; var emittance = material.Color; //material.emittance; var position = hit.Position; var normal = hit.Normal; if (Mode == RenderMode.Depth) { var dist = Distance(hit.Position, ray.Origin); var rate = 1 - (dist / maxDistance); rate = MathHelpres.Clamp(rate, 0, 1); rate *= rate; return(new Color(rate, rate, rate)); } if (Mode == RenderMode.Normals) { var x = normal.x; var y = normal.y; var z = normal.z; if (x < 0) { x *= -0.5f; } if (y < 0) { y *= -0.5f; } if (z < 0) { z *= -0.5f; } return(new Color(x, y, z)); } if (hit.HitObject.Light != null) { return(emittance); } if (Scene.LightingEnabled) { emittance = Enlight(emittance, hit); } if (material.Refraction > 0) { var newRayDirection = Refract(ray.Direction, normal, material.RefractionEta); var newRay = new Ray(position, newRayDirection); var incoming = TracePath(context, camera, newRay, back, depth + 1, hit.HitObject); var refractedColor = incoming; //emittance * incoming; emittance = Color.Lerp(emittance, refractedColor, material.Refraction); } if (material.Reflection > 0) { var newRayDirection = Reflect(ray.Direction, normal); var newRay = new Ray(position, newRayDirection); var BRDF = material.Specular / (float)Math.PI; var incoming = TracePath(context, camera, newRay, back, depth + 1, currentShape); var reflectedColor = !material.IsMetallic ? emittance + (BRDF * incoming) : incoming; emittance = Color.Lerp(emittance, reflectedColor, material.Reflection); } return(emittance); }
protected override void RenderScreen(RenderContext context) { var width = context.Width; var height = context.Height; var scale = context.Scale; var dispatcher = context.Dispatcher; var camera = MainCamera; var samples = 4; var samplesWidth = width * samples; var samplesHeight = height * samples; float fovScale = (float)Math.Tan(MathHelpres.DegToRad(camera.FOV * 0.5)); float aspectRatio = (float)width / height; Vector3 orig = camera.Position; float halfX = width / 2; float halfY = height / 2; Color[,] BatchPreview(int ix, int iy, int sizeX, int sizeY) { var tile = RenderBatch(ix, iy, sizeX, sizeY, (int)(8 * scale)); return(tile); } Color[,] Batch(int ix, int iy, int sizeX, int sizeY) { var tile = RenderBatch(ix, iy, sizeX, sizeY, 1); return(tile); } Color[,] RenderBatch(int ix, int iy, int sizeX, int sizeY, int step) { var tile = new Color[sizeX, sizeY]; for (int localY = 0; localY < sizeY; localY += step) { int y = iy + localY; for (int localX = 0; localX < sizeX; localX += step) { int x = ix + localX; // float posX = (2 * (x + 0.5f) / width - 1) * aspectRatio * fovScale; float posY = (1 - 2 * (y + 0.5f) / height) * fovScale; // var dir = Normalize(new Vector3(posX, posY, -1)); var ray = new Ray(orig, dir); // var color = TracePath(context, camera, ray, Scene.BackgroundColor); tile[localX, localY] = color; } } if (step > 1) { for (int localY = 0; localY < sizeY; localY += step) { for (int localX = 0; localX < sizeX; localX += step) { var template = tile[localX, localY]; for (var y = localY; y < localY + step && y < sizeY; y++) { for (var x = localX; x < localX + step && x < sizeX; x++) { tile[x, y] = template; } } } } } return(tile); } lock (camera) { lock (Scene) { BatchScreen(context, BatchPreview); BatchScreen(context, Batch); } } }