private List <IHittable> BvhPreprocess() { Hittables.Clear(); var planes = new List <IHittable>(); var hittablesToBvh = new List <IHittable>(); foreach (var model in Models) { if (model is Plane || model is Cylinder) { planes.Add(model); } else { hittablesToBvh.AddRange(((IHittable)model).Preprocess()); } } Hittables.AddRange(planes); if (hittablesToBvh != null && hittablesToBvh.Count > 0) { var node = new BvhNode(hittablesToBvh, 0, hittablesToBvh.Count); Hittables.Add(node); } return(Hittables); }
public BvhNode(Hitable[] hitables, int start, int length, float time0, float time1) { // TODO recursive -> iteration loop IComparer <Hitable> comparer = null; switch ((int)(3.0f * Util.UnitRandFloat())) { case 0: comparer = Boundary.compareX; break; case 1: comparer = Boundary.compareY; break; case 2: default: comparer = Boundary.compareZ; break; } System.Array.Sort(hitables, start, length, comparer); var halfLength = length / 2; switch (length) { case 1: left_ = hitables[start]; right_ = hitables[start]; break; case 2: left_ = hitables[start]; right_ = hitables[start + 1]; break; default: left_ = new BvhNode(hitables, start, halfLength, time0, time1); right_ = new BvhNode(hitables, start + halfLength, length - halfLength, time0, time1); break; } var boxLeft = left_.BoundingBox(time0, time1); if (!boxLeft.IsValid()) { Debug.Log("no bounding box detected."); } var boxRight = right_.BoundingBox(time0, time1); if (!boxRight.IsValid()) { Debug.Log("no bounding box detected."); } boundary_ = Boundary.SurroundingBoundary(boxLeft, boxRight); }
public static Model CreateFromBvh(BvhNode node) { // add nodes var model = new Model(Coordinates.Vrm1); model.Root.Name = "__bvh_root__"; AddBvhNodeRecursive(model, model.Root, node); return(model); }
public static Model CreateFromBvh(BvhNode node) { // add nodes var model = new Model(Coordinates.Gltf) { Root = new Node("__bvh_root__"), }; AddBvhNodeRecursive(model, model.Root, node); return(model); }
private Hitable[] OneWeekScene() { var center = new Vector3(4.0f, 2.0f, 0.0f); var position = new Vector3(0.0f, -1000.0f, 0.0f); var hitables = new List <Hitable>(500); hitables.Add(new Sphere(position, -position.y, new Lambertian(0.5f * Vector3.one))); float radius = 0.2f; var dielectric = new Dielectric(1.5f); for (int a = -11; a < 11; ++a) { for (int b = -11; b < 11; ++b) { position.Set(a + 0.9f * Util.UnitRandFloat(), radius, b + 0.9f * Util.UnitRandFloat()); if ((position - center).sqrMagnitude <= 0.81) { continue; } var chooseMat = Util.UnitRandFloat(); if (chooseMat < 0.8f) { // hitables.Add(new Sphere(position, radius, new Lambertian(new Vector3(Util.UnitRandFloat(), Util.UnitRandFloat(), Util.UnitRandFloat())))); hitables.Add(new MovingSphere(position, position + new Vector3(0.0f, 0.5f * Util.UnitRandFloat(), 0.0f), 0.0f, 1.0f, radius, new Lambertian(new Vector3(Util.UnitRandFloat(), Util.UnitRandFloat(), Util.UnitRandFloat())))); continue; } if (chooseMat < 0.95f) { hitables.Add(new Sphere(position, radius, new Metal(new Vector3(0.5f * (1.0f + Util.UnitRandFloat()), 0.5f * (1.0f + Util.UnitRandFloat()), 0.5f * (1.0f + Util.UnitRandFloat())), 0.5f * (1.0f + Util.UnitRandFloat())))); continue; } hitables.Add(new Sphere(position, radius, dielectric)); } } radius = 1.0f; position.Set(0.0f, 1.0f, 0.0f); hitables.Add(new Sphere(position, radius, dielectric)); position.Set(-4.0f, 1.0f, 0.0f); hitables.Add(new Sphere(position, radius, new Lambertian(new Vector3(0.4f, 0.2f, 0.1f)))); position.Set(4.0f, 1.0f, 0.0f); hitables.Add(new Sphere(position, radius, new Metal(new Vector3(0.7f, 0.6f, 0.5f), 0.0f))); var retval = new Hitable[1]; retval[0] = new BvhNode(hitables.ToArray(), 0, hitables.Count, 0.0f, 1.0f); return(retval); }
static void BuildHierarchy(Transform parent, BvhNode node, float toMeter) { var go = new GameObject(node.Name); go.transform.localPosition = node.Offset.ToXReversedVector3() * toMeter; go.transform.SetParent(parent, false); //var gizmo = go.AddComponent<BoneGizmoDrawer>(); //gizmo.Draw = true; foreach (var child in node.Children) { BuildHierarchy(go.transform, child, toMeter); } }
static void AddBvhNodeRecursive(Model model, Node parent, BvhNode node) { var newNode = new Node(node.Name) { HumanoidBone = node.Bone, }; model.Nodes.Add(newNode); parent.Add(newNode); newNode.Translation = node.SkeletonLocalPosition; foreach (var child in node.Children) { AddBvhNodeRecursive(model, newNode, child); } }
static BvhNode GetNode(BvhNode root, string path) { var splitted = path.Split('/'); var it = splitted.Select(x => x).GetEnumerator(); var current = root; if (splitted[0] == path) { return(current); } it.MoveNext(); while (it.MoveNext()) { current = current.Children.First(x => x.Name == it.Current); } return(current); }
public static void Main(string[] args) { var aspect = 1; //var generator = new RandomWorld(); //var generator = new TwoSpheres(); //var generator = new PerlinTest(); //var generator = new EarthTest(); //var generator = new SimpleLightTest(); //var generator = new RectTest(); //var generator = new CornellBox(); //var generator = new CornellSmoke(); var generator = new NextWeekScene(); var imageWidth = 400; var imageHeight = (int)(imageWidth / aspect); var cam = generator.GetCamera(aspect); var objects = generator.Generate(); var world = new BvhNode(objects, 0, objects.Count, 0, 1); var start = DateTime.Now; var image = new Image(imageWidth, imageHeight); var samplesPerPixel = 1024; var maxDepth = 50; var linesRemaining = imageHeight; //for(var y = 0; y < image.Height; y++) Parallel.For(0, image.Height, y => { var lineStart = DateTime.Now; for (var x = 0; x < image.Width; x++) { Vec3 pixelColor = Vec3.Zero; //var sampleOffsets = Vec3.GenerateWhite2DNoise((int) Math.Sqrt(samplesPerPixel)); var sampleOffsets = Vec3.GenerateJittered2DNoise((int)Math.Sqrt(samplesPerPixel)); var sampleWeights = Vec3.GenerateConstantSampleWeights((int)Math.Sqrt(samplesPerPixel)); for (var i = 0; i < sampleOffsets.Count; i++) { var u = (x + sampleOffsets[i].x) / (imageWidth - 1); var v = (y + sampleOffsets[i].y) / (imageHeight - 1); var ray = cam.GetRay(u, v); pixelColor += ray.GetColor(world, maxDepth, cam.Background) * sampleWeights[i]; } image.SetPixel(x, y, pixelColor.GammaCorrected()); } Interlocked.Decrement(ref linesRemaining); var lineTime = DateTime.Now - lineStart; Console.WriteLine($"Lines remaining: {linesRemaining}, last line time: {lineTime}"); }); var end = DateTime.Now; var diff = end - start; Console.WriteLine($"Render Time: {diff}"); Console.WriteLine($"Num Rays: {Ray.RayCount}"); Console.WriteLine($"Rays per second: {Ray.RayCount / diff.TotalSeconds}"); var file = $"render-{DateTime.Now:yyyyMMdd-HH_mm_ss}.ppm"; image.WriteToPpm(file); }