Пример #1
0
    public XZTriangle(float x0, float x1, float x2, float z0, float z1, float z2, float k, Material mat)
    {
        this.x0  = x0;
        this.x1  = x1;
        this.z0  = z0;
        this.z1  = z1;
        this.x2  = x2;
        this.z2  = z2;
        this.k   = k;
        this.mat = mat;
        float xMin = Mathf.Min(Mathf.Min(x0, x1), x2);
        float xMax = Mathf.Max(Mathf.Max(x0, x1), x2);
        float zMin = Mathf.Min(Mathf.Min(z0, z1), z2);
        float zMax = Mathf.Max(Mathf.Max(z0, z1), z2);

        rect = new XZRect(xMin, xMax, zMin, zMax, k, mat);
    }
Пример #2
0
        private void InitScene()
        {
            int      width       = 512;
            int      height      = 512;
            bool     isSky       = false;
            Vector3D lookFrom    = new Vector3D(278, 278, -800);
            Vector3D lookAt      = new Vector3D(278, 278, 0);
            float    diskToFocus = 10;
            float    aperture    = 0;
            float    vfov        = 40;
            Camera   camera      = new Camera(lookFrom, lookAt, new Vector3D(0, 1, 0), vfov,
                                              (float)width / (float)height, aperture, diskToFocus, 0, 1);

            List <Hitable> list = new List <Hitable>();

            Material red   = new Lambertian(new ConstantTexture(new Vector3D(0.65f, 0.05f, 0.05f)));
            Material white = new Lambertian(new ConstantTexture(new Vector3D(0.73f, 0.73f, 0.73f)));
            Material green = new Lambertian(new ConstantTexture(new Vector3D(0.12f, 0.45f, 0.15f)));
            Material light = new DiffuseLight(new ConstantTexture(new Vector3D(7, 7, 7)));

            list.Add(new FlipNormals(new XZTriangle(113, 443, 278, 127, 127, 432, 554, light)));
            list.Add(new FlipNormals(new YZRect(0, 555, 0, 555, 555, green)));
            list.Add(new YZRect(0, 555, 0, 555, 0, red));
            list.Add(new FlipNormals(new XZRect(0, 555, 0, 555, 555, white)));
            list.Add(new XZRect(0, 555, 0, 555, 0, white));
            list.Add(new FlipNormals(new XYRect(0, 555, 0, 555, 555, white)));
            Hitable b1 = new Translate(new RotateY(new Box(new Vector3D(0, 0, 0),
                                                           new Vector3D(165, 165, 165), white), -18), new Vector3D(130, 0, 65));
            Hitable b2 = new Translate(new RotateY(new Box(new Vector3D(0, 0, 0),
                                                           new Vector3D(165, 330, 165), white), 15), new Vector3D(265, 0, 295));

            list.Add(new ConstantMedium(b1, 0.01f, new ConstantTexture(new Vector3D(1, 1, 1))));
            list.Add(new ConstantMedium(b2, 0.01f, new ConstantTexture(new Vector3D(0, 0, 0))));
            BVHNode     b     = new BVHNode(list, list.Count, 0, 1);
            HitableList world = new HitableList();

            world.list.Add(b);


            HitableList lightShapeList = new HitableList();
            Hitable     lightShape     = new XZRect(113, 443, 127, 432, 554, null);

            lightShapeList.list.Add(lightShape);
            scene = new Scene(width, height, world, isSky, camera, 0.5f, true, lightShapeList);
        }
Пример #3
0
    private void LinearScanner(object o)
    {
        ScannerCofig config = (ScannerCofig)o;

        for (int j = 0; j < config.height; j++)
        {
            for (int i = 0; i < config.width; i++)
            {
                Vector3D color      = new Vector3D(0, 0, 0);
                float    u          = (float)(i + Mathf.Randomfloat()) / (float)width;
                float    v          = 1 - (float)(j + Mathf.Randomfloat()) / (float)height;
                Ray      ray        = camera.GetRay(u, v);
                Hitable  lightShape = new XZRect(213, 343, 227, 332, 554, new Lambertian());
                color = GetColor(ray, world, lightShape, 0);
                // color = new Vector3D(Mathf.Sqrt(color.X), Mathf.Sqrt(color.Y), Mathf.Sqrt(color.Z));//这里不应进行伽马校正
                SetPixel(i, j, color);
            }
        }
    }
Пример #4
0
    private Vector3D GetColor(Ray r, HitableList world, int depth)
    {
        HitRecord rec;

        /*这里的0.001不能改为0,当tmin设0的时候会导致,遍历hitlist时候,ray的t求解出来是0,
         * hit的时候全走了else,导致递归到50层的时候,最后return的是0,* attenuation结果还是0。
         * 距离越远,散射用到random_in_unit_sphere生成的ray误差越大
         */
        if (world.Hit(r, 0.001f, float.MaxValue, out rec))
        {
            Ray      scattered;
            Vector3D emitted = rec.matPtr.Emitted(r, rec, rec.u, rec.v, rec.p);
            Vector3D albedo;
            float    pdfVal;
            if (depth < 50 && rec.matPtr.Scatter(r, rec, out albedo, out scattered, out pdfVal))
            {
                Hitable    lightSphape = new XZRect(213, 343, 227, 332, 554, new Lambertian());
                HitablePDF p0          = new HitablePDF(lightSphape, rec.p);
                CosinePDF  p1          = new CosinePDF(rec.normal);
                MixturePDF p           = new MixturePDF(p0, p1);
                scattered = new Ray(rec.p, p.Generate(), r.Time);
                pdfVal    = p.Value(scattered.Direction);
                Vector3D color = GetColor(scattered, world, depth + 1);       //每次光线衰减之后深度加一
                return(emitted + rec.matPtr.ScatteringPDF(r, rec, scattered)
                       * new Vector3D(albedo.X * color.X, albedo.Y * color.Y, albedo.Z * color.Z) / pdfVal);
            }
            else
            {
                return(emitted);
            }
        }
        else
        {
            //Vector3D unitDirection = r.Direction.UnitVector();
            //float t = 0.5f * (unitDirection.Y + 1f);
            //return (1 - t) * new Vector3D(1, 1, 1) + t * new Vector3D(0.5f, 0.7f, 1);
            return(new Vector3D(0, 0, 0));
        }
    }
Пример #5
0
    private void LinearScanner(object o)
    {
        ScannerCofig config      = (ScannerCofig)o;
        Hitable      lightShape  = new XZRect(213, 343, 227, 332, 554, null);
        Hitable      glassSphere = new Sphere(new Vector3D(190, 90, 190), 90, null);

        for (int j = 0; j < config.height; j++)
        {
            for (int i = 0; i < config.width; i++)
            {
                Vector3D       color = new Vector3D(0, 0, 0);
                float          u     = (float)(i + Mathf.Randomfloat()) / (float)width;
                float          v     = 1 - (float)(j + Mathf.Randomfloat()) / (float)height;
                Ray            ray   = camera.GetRay(u, v);
                List <Hitable> a     = new List <Hitable>();
                a.Add(lightShape);
                a.Add(glassSphere);
                HitableList hitableList = new HitableList(a);
                color = DeNaN(GetColor(ray, world, hitableList, 0));
                color = new Vector3D(Mathf.Sqrt(color.X), Mathf.Sqrt(color.Y), Mathf.Sqrt(color.Z));
                SetPixel(i, j, color);
            }
        }
    }
Пример #6
0
        private void InitScene()
        {
            int      width       = 512;
            int      height      = 512;
            bool     isSky       = false;
            Vector3D lookFrom    = new Vector3D(500, 300, -600);
            Vector3D lookAt      = new Vector3D(278, 278, 0);
            float    diskToFocus = 10;
            float    aperture    = 0;
            float    vfov        = 40;
            Camera   camera      = new Camera(lookFrom, lookAt, new Vector3D(0, 1, 0), vfov,
                                              (float)width / (float)height, aperture, diskToFocus, 0, 1);

            List <Hitable> list     = new List <Hitable>();
            List <Hitable> boxList  = new List <Hitable>();
            List <Hitable> boxList2 = new List <Hitable>();

            int      nb     = 20;
            Material white  = new Lambertian(new ConstantTexture(new Vector3D(0.73f, 0.73f, 0.73f)));
            Material ground = new Lambertian(new ConstantTexture(new Vector3D(0.48f, 0.83f, 0.53f)));
            Material light  = new DiffuseLight(new ConstantTexture(new Vector3D(7, 7, 7)));

            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 * (Mathf.Randomfloat() + 0.01f);
                    float z1 = z0 + w;
                    boxList.Add(new Box(new Vector3D(x0, y0, z0), new Vector3D(x1, y1, z1), ground));
                }
            }
            list.Add(new BVHNode(boxList, boxList.Count, 0, 1));
            list.Add(new FlipNormals(new XZRect(123, 423, 147, 412, 554, light)));
            Vector3D center = new Vector3D(400, 400, 200);

            list.Add(new MovingSphere(center, center + new Vector3D(30, 0, 0), 0, 1, 50,
                                      new Lambertian(new ConstantTexture(new Vector3D(0.7f, 0.3f, 0.1f)))));
            list.Add(new Sphere(new Vector3D(260, 150, 45), 50, new Dielectric(1.5f)));
            list.Add(new Sphere(new Vector3D(0, 150, 145), 50, new Metal(
                                    new Vector3D(0.8f, 0.8f, 0.9f), 10)));
            Hitable boundary = new Sphere(new Vector3D(360, 150, 145), 70, new Dielectric(1.5f));

            list.Add(boundary);
            list.Add(new ConstantMedium(boundary, 0.2f, new ConstantTexture(new Vector3D(0.2f, 0.4f, 0.9f))));
            boundary = new Sphere(new Vector3D(0, 0, 0), 5000, new Dielectric(1.5f));
            list.Add(new ConstantMedium(boundary, 0.0001f, new ConstantTexture(new Vector3D(1, 1, 1))));

            Material emat = new Lambertian(new Imagetexture("Earth.jpg"));

            list.Add(new Sphere(new Vector3D(400, 200, 400), 100, emat));
            Texture pertext = new NoiseTexture(1f);

            list.Add(new Sphere(new Vector3D(220, 280, 300), 80, new Lambertian(pertext)));
            int ns = 1000;

            for (int j = 0; j < ns; j++)
            {
                boxList2.Add(new Sphere(new Vector3D(165 * Mathf.Randomfloat(), 165 * Mathf.Randomfloat(), 165 * Mathf.Randomfloat()), 10, white));
            }
            list.Add(new Translate(new RotateY(new BVHNode(boxList2, ns, 0, 1), 15), new Vector3D(-100, 270, 395)));


            BVHNode     b     = new BVHNode(list, list.Count, 0, 1);
            HitableList world = new HitableList();

            world.list.Add(b);


            HitableList lightShapeList = new HitableList();
            Hitable     lightShape     = new XZRect(123, 423, 147, 412, 554, null);

            lightShapeList.list.Add(lightShape);
            scene = new Scene(width, height, world, isSky, camera, 0.5f, false, lightShapeList);
        }