public BVHNode(Hitable[] list, int low, int high, float t0, float t1)
        {
            if (low < 0 || high > list.Length)
            {
                throw new Exception("BVHNode Contruction error low <0 || high >list.Length");
            }
            int length = high - low;

            if (length <= 0)
            {
                throw new Exception("BVHNode Contruction error low >= high");
            }

            if (length == 1)
            {
                _left = _right = list[low];
                _box  = _left.BoundVolume(t0, t1);
            }
            else if (length == 2)
            {
                _left  = list[low];
                _right = list[low + 1];
                _box   = AABB.SurroundingBox(_left.BoundVolume(t0, t1), _right.BoundVolume(t0, t1));
            }
            else
            {
                Array.Sort(list, low, high - low, new BVHComparer((int)(3 * Exten.rand01())));
                int mid = (low + high) / 2;
                _left  = new BVHNode(list, low, mid, t0, t1);
                _right = new BVHNode(list, mid, high, t0, t1);
                _box   = AABB.SurroundingBox(_left.BoundVolume(t0, t1), _right.BoundVolume(t0, t1));
            }
        }
Exemple #2
0
        public Ray GenRay(float s, float t)
        {
            vec3 offset = lenRadius * random_in_unit_disk();
            var  point  = origin + offset;
            var  time   = openTime + (closeTime - openTime) * Exten.rand01();

            return(new Ray(point, lower_left_corner + s * horizontal + t * vertical - point, time));
        }
Exemple #3
0
        vec3 random_in_unit_disk()
        {
            vec3 p;

            do
            {
                p = 2.0f * new vec3(Exten.rand01(), Exten.rand01(), 0) - new vec3(1, 1, 0);
            } while (glm.dot(p, p) >= 1.0f);
            return(p);
        }
Exemple #4
0
 void shuff(int [] vs)
 {
     for (int i = 0; i < vs.Length - 1; ++i)
     {
         int nextIdx = i + 1 + (int)((vs.Length - i - 1) * Exten.rand01());
         var temp    = vs[i];
         vs[i]       = vs[nextIdx];
         vs[nextIdx] = temp;
     }
 }
 public  vec3 RandomCosineDir()
 {
     float r1 = Exten.rand01();
     float r2 = Exten.rand01() / fuzz;
     r2 = (float)Math.Pow(2.72, -r2*r2);
     double z = Math.Sqrt(1 - r2);
     double phi = 2 * Math.PI * r1;
     double x = Math.Cos(phi) * Math.Sqrt(r2);
     double y = Math.Sin(phi) * Math.Sqrt(r2);
     return new vec3((float)x, (float)y, (float)z);
 }
Exemple #6
0
        public vec3 Generate(vec3 point, vec3 normal)
        {
            float r1 = Exten.rand01();
            float r2 = Exten.rand01();

            var   pc     = _sphere.GetCenter(0) - point;
            float cosMax = MathF.Sqrt(1 - _sphere.radius * _sphere.radius / glm.dot(pc, pc));
            float z      = 1 + r2 * (cosMax - 1);
            float phi    = r1 * 2.0f * MathF.PI;
            float x      = MathF.Cos(phi) * MathF.Sqrt(1 - z * z);
            float y      = MathF.Sin(phi) * MathF.Sqrt(1 - z * z);
            ONB   oNB    = new ONB(glm.normalize(pc));

            return(oNB.Local(x, y, z));
        }
Exemple #7
0
 public Noise()
 {
     for (int i = 0; i < _randomValue.Length; ++i)
     {
         _randomValue[i] = Exten.rand01();
     }
     for (int i = 0; i < maxL; ++i)
     {
         _xAxis[i] = i; //(int)(maxL * Exten.rand01());
         _yAxis[i] = i; //(int)(maxL * Exten.rand01());
         _zAxis[i] = i; //(int)(maxL * Exten.rand01());
     }
     shuff(_xAxis);
     shuff(_yAxis);
     shuff(_zAxis);
 }
Exemple #8
0
        public vec3 Generate(vec3 point, vec3 normal)
        {
            var r = Exten.rand01();

            if (r < 0.5f)
            {
                return(_pdfs[0].Generate(point, normal));
            }
            else if (r < 0.75f)
            {
                return(_pdfs[1].Generate(point, normal));
            }
            else
            {
                return(_pdfs[2].Generate(point, normal));
            }
        }
Exemple #9
0
        static Hitable FinalTest()
        {
            int nb = 20;

            Hitable[] list    = new Hitable[30];
            Hitable[] boxlist = new Hitable[10000];
            Material  ground  = new Lambertian(new SolidTexture(new vec3(0.48f, 0.83f, 0.53f)));
            int       b       = 0;

            for (int i = 0; i < nb; i++)
            {
                for (int j = 0; j < nb; j++)
                {
                    float w  = 100;
                    float x0 = -1000 + i * w;
                    float z0 = -1000 + j * w;
                    float y0 = 0;
                    float x1 = x0 + w;
                    float y1 = 100 * (Exten.rand01() + 0.01f);
                    float z1 = z0 + w;
                    boxlist[b++] = new Box(new vec3(x0, y0, z0), new vec3(x1, y1, z1), ground);
                }
            }
            int l = 0;

            list[l++] = new BVHNode(boxlist, 0, b, 0, 1);
            Material light = new DiffuseLight(new SolidTexture(new vec3(7, 7, 7)));

            list[l++] = new XZRect(554, 123, 423, 147, 412, light);
            vec3 center = new vec3(400, 400, 200);

            //public Sphere(vec3 c, vec3 c1, float r, Material m, float time1, float time2)
            list[l++] = new Sphere(center, center + new vec3(30, 0, 0), 50, new Lambertian(new SolidTexture(new vec3(0.7f, 0.3f, 0.1f))), 0, 1);
            list[l++] = new Sphere(new vec3(260, 150, 45), 50, new Dieletric(1.5f));
            list[l++] = new Sphere(new vec3(0, 150, 145), 50, new Metal(new vec3(0.8f, 0.8f, 0.9f), 10.0f));
            Hitable boundary = new Sphere(new vec3(360, 150, 145), 70, new Dieletric(1.5f));

            list[l++] = boundary;
            boundary  = new Sphere(new vec3(0, 0, 0), 5000, new Dieletric(1.5f));
            Texture pertext = new NoiseTexture(new Noise());

            list[l++] = new Sphere(new vec3(220, 280, 300), 80, new Lambertian(pertext));
            return(new HitList(list.Where(arg => arg != null).ToArray()));
        }
        public bool Scatter(Ray ray, HitRecord hitRecord, out ScatterRecord sRecord)
        {
            sRecord = new ScatterRecord();
            var normal = hitRecord.normal;
            var point = hitRecord.point;
            sRecord.attenuation = new vec3(1.0f, 1.0f, 1.0f);
            float eta = ref_idx;
            var n = normal;


            if (glm.dot(ray.direction, normal) > 0)//从内到外
            {
                n = new vec3(-normal.x, -normal.y, -normal.z);
            }
            else
            {
                eta = 1.0f / eta;
            }

            vec3 r;
            float prob = 1.0f;
            if (Exten.refract(ray.direction, n, eta, out r))
            {
                float cosi = -glm.dot(ray.direction, n);
                float cost = -glm.dot(r, n);
                prob = fresnel(cosi, cost, eta);
            }
            if (Exten.rand01() < prob)
            {
                vec3 reflected = Exten.reflect(ray.direction, normal);
                sRecord.pdf = new ConstPDF(reflected);
            }
            else
            {
                sRecord.pdf = new ConstPDF(r);
            }

            return true;

        }
Exemple #11
0
 static float drand48()
 {
     return(Exten.rand01());
 }
Exemple #12
0
        public static void Main(string[] args)
        {
            Exten.r = new Random(0);
            int    width       = 600;
            int    height      = 300;
            string outPath     = "1.png";
            int    sampleCount = 5;
            bool   bvh         = false;

            if (args.Length >= 1)
            {
                sampleCount = int.Parse(args[0]);
            }
            if (args.Length >= 2)
            {
                width = int.Parse(args[1]);
            }
            if (args.Length >= 3)
            {
                height = int.Parse(args[2]);
            }
            if (args.Length >= 4)
            {
                outPath = args[3];
            }
            if (args.Length >= 5)
            {
                bvh = bool.Parse(args[4]);
            }
            scene = CornellBox(); // SimpleLight(); //random_scene(bvh);
            vec3  lookfrom      = new vec3(278, 278, -800);
            vec3  lookat        = new vec3(278, 278, 0);
            float dist_to_focus = 10.0f;
            float aperture      = 0.0f;


            Camera camera = new Camera(lookfrom, lookat, new vec3(0, 1, 0), 40, (float)(width) / (float)(height), aperture, dist_to_focus, 0, 1);
            Bitmap bmp    = new Bitmap(width, height);

            for (int i = height - 1; i >= 0; --i)
            {
                ShowProgress((height - i) / (float)height);
                for (int j = 0; j < width; ++j)
                {
                    var c = new vec3(0, 0, 0);
                    for (int k = 0; k < sampleCount; ++k)
                    {
                        float x   = (j + Exten.rand01()) / (float)width;
                        float y   = (i + Exten.rand01()) / (float)height;
                        var   ray = camera.GenRay(x, y);
                        c += RayTracing(ray, 0);
                    }
                    c /= sampleCount;
                    //printColor(c.gamma());

                    c = c.gamma();
                    int r = (int)(c.x * 255.99f);
                    int g = (int)(c.y * 255.99f);
                    int b = (int)(c.z * 255.99f);
                    r = clamp(r, 0, 255);
                    g = clamp(g, 0, 255);
                    b = clamp(b, 0, 255);
                    Color o = Color.FromArgb(r, g, b);
#if UNITY_EDITOR
                    bmp.SetPixel(j, i, o);
#else
                    bmp.SetPixel(j, height - i - 1, o);
#endif
                }
            }
            bmp.Save(outPath, ImageFormat.Png);
            HideProgress();
        }