Пример #1
0
        private static Scene TeapotScene(int width, int height, out Stopwatch stopwatch, out Camera camera)
        {
            stopwatch = Stopwatch.StartNew();

            Sphere[] spheres = new Sphere[]
            {
                new Sphere(new Vector3(0, -100.5f, -1), 100, new LambertianMaterial(new Vector3(.8f, .8f, .8f))),
                new Sphere(new Vector3(2, 0, -1), 0.5f, new LambertianMaterial(new Vector3(0.8f, 0.4f, 0.4f))),
                new Sphere(new Vector3(0, 0, -1), 0.5f, new LambertianMaterial(new Vector3(0.4f, 0.8f, 0.4f))),
                new Sphere(new Vector3(-2, 0, -1), 0.5f, new MetalMaterial(new Vector3(.4f, .4f, .8f), 0)),
                new Sphere(new Vector3(2, 0, 1), 0.5f, new MetalMaterial(new Vector3(.4f, .8f, .4f), 0)),
                new Sphere(new Vector3(0, 0, 1), 0.5f, new MetalMaterial(new Vector3(.4f, .8f, .4f), 0.2f)),
                new Sphere(new Vector3(-2, 0, 1), 0.5f, new MetalMaterial(new Vector3(.4f, .8f, .4f), 0.6f)),
                new Sphere(new Vector3(0.5f, 1.25f, 0.5f), 0.5f, new DielectricMaterial(1.5f)),
                //new Sphere(new Vector3(-1.5f,1.5f,0f), 0.3f, new LambertianMaterial(new Vector3(.8f, .6f, .2f)))
            };

            Scene                scene             = new Scene();
            TriangleHitSystem    triangleHitSystem = scene.GetOrCreateHitSystem <TriangleHitSystem>();
            SceneSphereHitSystem sphereHitSystem   = scene.GetOrCreateHitSystem <SceneSphereHitSystem>();

            for (int i = 0; i < spheres.Length; i++)
            {
                sphereHitSystem.Add(spheres[i]);
            }

            List <Triangle> triangles = new List <Triangle>();

            WavefrontLoader.Load(File.ReadAllText(@"Resources/Teapot/teapot.obj"), ref triangles);

            var mat = new MetalMaterial(new Vector3(1, .84f, 0), .01f);

            // var mat = new DielectricMaterial(1.5f);
            for (int i = 0; i < triangles.Count; i++)
            {
                var tri = triangles[i];
                tri.p1 *= .01f;                          // Scale down
                tri.p2 *= .01f;                          // Scale down
                tri.p3 *= .01f;                          // Scale down
                tri.p1 += new Vector3(-1.5f, 1.25f, 0f); // Translate
                tri.p2 += new Vector3(-1.5f, 1.25f, 0f); // Translate
                tri.p3 += new Vector3(-1.5f, 1.25f, 0f); // Translate

                tri.material = mat;

                triangleHitSystem.Add(tri);
            }

            // triangleHitSystem.Add(new Triangle(new Vector3(-2, 0, 1), new Vector3(0, 1, 1), new Vector3(2, 0, 1), mat));

            scene.PrepareForRendering();
            stopwatch.Stop();
            camera = new Camera(new Vector3(0, 2, 3), new Vector3(0, 0, 0), new Vector3(0, 1, 0), 70, (float)width / (float)height, 0.025f, 3f);

            return(scene);
        }
Пример #2
0
    public virtual void GenerateQuality(int value)
    {
        if (value > 7)
        {
            value = 7;
        }
        if (material == Material.Metal)
        {
            MetalMaterial randomMaterial = RandomEnum.IndexOf <MetalMaterial>(value);

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Wood)
        {
            WoodMaterial randomMaterial = RandomEnum.IndexOf <WoodMaterial>(value);

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Cloth)
        {
            LightMaterial randomMaterial = RandomEnum.IndexOf <LightMaterial>(value);

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Leather)
        {
            LeatherMaterial randomMaterial = RandomEnum.IndexOf <LeatherMaterial>(value);

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Gem)
        {
            GemMaterial randomMaterial = RandomEnum.IndexOf <GemMaterial>(value);

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }


        //change values based on material quality;
        defence *= levelMultiplyer;
    }
Пример #3
0
    public virtual void GenerateQuality()   //if value <0 do random value. testing random material generation.
    {
        if (material == Material.Metal)
        {
            MetalMaterial randomMaterial = RandomEnum.Of <MetalMaterial>();

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Wood)
        {
            WoodMaterial randomMaterial = RandomEnum.Of <WoodMaterial>();

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Cloth)
        {
            LightMaterial randomMaterial = RandomEnum.Of <LightMaterial>();

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Leather)
        {
            LeatherMaterial randomMaterial = RandomEnum.Of <LeatherMaterial>();

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }
        else if (material == Material.Gem)
        {
            GemMaterial randomMaterial = RandomEnum.Of <GemMaterial>();

            name            = randomMaterial.ToString() + " " + name;
            levelMultiplyer = (int)randomMaterial + 1;//starts at zero
        }


        //change values based on material quality;
        defence *= levelMultiplyer;
        //attackSpeed *= levelMultiplyer;??
    }
Пример #4
0
        /// <inheritdoc />
        public IHitable GetWorld()
        {
            var red      = new LambertianMaterial(new ColorTexture(0.65f, 0.05f, 0.05f));
            var white    = new LambertianMaterial(new ColorTexture(0.73f, 0.73f, 0.73f));
            var green    = new LambertianMaterial(new ColorTexture(0.12f, 0.45f, 0.15f));
            var aluminum = new MetalMaterial(new ColorVector(0.8f, 0.85f, 0.88f), 0.0f);

            var list = new HitableList()
            {
                new FlipNormals(new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, green)),
                new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, red),
                new FlipNormals(_light),
                new FlipNormals(new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),
                new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, white),
                new FlipNormals(new XyRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),

                // new Translate(new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 165.0f, 165.0f), white), -18.0f), new Vector3(130.0f, 0.0f, 65.0f)),
                new Translate(new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 330.0f, 165.0f), white), 15.0f), new Vector3(265.0f, 0.0f, 295.0f)),
                _glassSphere,
            };

            return(new BvhNode(list, 0.0f, 1.0f));
        }
Пример #5
0
        private static IScene Build()
        {
            var white =
                new MatteMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 1f, 1f, 1f }, SpectrumType.Illuminant)),
                    new ConstantTexture <float>(0), null);

            var red =
                new PlasticMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 1f, 0f, 0f }, SpectrumType.Illuminant)),
                    new ConstantTexture <Spectrum>(new Spectrum(0.3f)),
                    new ConstantTexture <float>(0.0f),
                    null,
                    true);

            var yellow =
                new MatteMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 1f, 1f, 0f }, SpectrumType.Illuminant)),
                    new ConstantTexture <float>(0), null);

            var cyan =
                new MatteMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 0f, 1f, 1f }, SpectrumType.Illuminant)),
                    new ConstantTexture <float>(0), null);

            var metal =
                new MetalMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 0.8f, 0.8f, 0.8f }, SpectrumType.Illuminant)),
                    new ConstantTexture <Spectrum>(Spectrum.One),
                    new ConstantTexture <float>(0.01f), null, null, null, true);

            var mirror =
                new MirrorMaterial(
                    new ConstantTexture <Spectrum>(Spectrum.FromRGB(new[] { 0.8f, 0.8f, 0.8f }, SpectrumType.Illuminant)),
                    null);


            var s1t = Transform.Translate(278, 278, 100);
            var s1  = new Sphere(s1t, Transform.Invert(s1t), false, 100f, -100, 100, 360);
            var s1g = new GeometricPrimitive(s1, mirror, null);

            var s2t = Transform.Translate(340, 100, 80);
            var s2  = new Sphere(s2t, Transform.Invert(s2t), false, 120f, -120, 120, 360);
            var s2g = new GeometricPrimitive(s2, cyan, null);

            var s3t = Transform.Translate(0, 278, 200);
            var s3  = new Sphere(s3t, Transform.Invert(s3t), false, 300f, -300, 300, 360);
            var s3g = new GeometricPrimitive(s3, yellow, null);

            var s4t = Transform.Translate(400, 500, 150);
            var s4  = new Sphere(s4t, Transform.Invert(s4t), false, 180f, -180, 180, 360);
            var s4g = new GeometricPrimitive(s4, metal, null);

            var s5t = Transform.Translate(420, 200, 250);
            var s5  = new Sphere(s5t, Transform.Invert(s5t), false, 180f, -180, 180, 360);
            var s5g = new GeometricPrimitive(s5, white, null);

            var s6t = Transform.Translate(500, 30, 180);
            var s6  = new Sphere(s6t, Transform.Invert(s6t), false, 200f, -200, 200, 360);
            var s6g = new GeometricPrimitive(s6, red, null);

            var bvh = new BVH(new IPrimitive[] { s1g, s2g, s3g, s4g, s5g, s6g }, SplitMethod.HLBVH);

            var lt         = Transform.Translate(400, 900, -800);
            var s          = Spectrum.FromBlackbodyT(5500) * 2000000f;
            var pointLight = new PointLight(lt, null, s);

            return(new Scene(bvh, new ILight[] { pointLight }));
        }
Пример #6
0
    public static Material GetMetalMaterial(MetalMaterial mtype, MeshFilter mf, byte i_illumination)
    {
        float illumination = i_illumination / 255f;
        float p            = 1f / (MAX_MATERIAL_LIGHT_DIVISIONS + 1); // цена деления на шкале освещенности

        if (illumination < p / 2f)
        {
            return(darkness_material);
        }

        Mesh quad = mf.mesh;

        if (quad == null)
        {
            return(metal_material);
        }
        float piece = 0.25f;

        Vector2[] borders;
        switch (mtype)
        {
        default:
        case MetalMaterial.MetalK:
            borders = new Vector2[] { new Vector2(0, 3 * piece), new Vector2(0, 4 * piece), new Vector2(piece, 4 * piece), new Vector2(piece, 3 * piece) };
            break;

        case MetalMaterial.MetalM:
            borders = new Vector2[] { new Vector2(piece, 3 * piece), new Vector2(piece, 4 * piece), new Vector2(2 * piece, 4 * piece), new Vector2(2 * piece, 3 * piece) };
            break;

        case MetalMaterial.MetalE:
            borders = new Vector2[] { new Vector2(2 * piece, 3 * piece), new Vector2(2 * piece, 4 * piece), new Vector2(3 * piece, 4 * piece), new Vector2(3 * piece, 3 * piece) };
            break;

        case MetalMaterial.MetalN:
            borders = new Vector2[] { new Vector2(3 * piece, 3 * piece), new Vector2(3 * piece, 4 * piece), new Vector2(4 * piece, 4 * piece), new Vector2(4 * piece, 3 * piece) };
            break;

        case MetalMaterial.MetalP:
            borders = new Vector2[] { new Vector2(0, 2 * piece), new Vector2(0, 3 * piece), new Vector2(piece, 3 * piece), new Vector2(piece, 2 * piece) };
            break;

        case MetalMaterial.MetalS:
            borders = new Vector2[] { new Vector2(piece, 2 * piece), new Vector2(piece, 3 * piece), new Vector2(2 * piece, 3 * piece), new Vector2(2 * piece, 2 * piece) };
            break;
        }
        bool isQuad = (quad.uv.Length == 4);

        Vector2[] uvEdited = quad.uv;
        if (isQuad)
        {
            borders = new Vector2[] { borders[0] + Vector2.one * 0.01f, borders[1] + new Vector2(0.01f, -0.01f), borders[2] - Vector2.one * 0.01f, borders[3] - new Vector2(0.01f, -0.01f) };
            if (useTextureRotation)
            {
                float seed = Random.value;
                if (seed > 0.5f)
                {
                    if (seed > 0.75f)
                    {
                        uvEdited = new Vector2[] { borders[0], borders[2], borders[3], borders[1] }
                    }
                    ;
                    else
                    {
                        uvEdited = new Vector2[] { borders[2], borders[3], borders[1], borders[0] }
                    };
                }
                else
                {
                    if (seed > 0.25f)
                    {
                        uvEdited = new Vector2[] { borders[3], borders[1], borders[0], borders[2] }
                    }
                    ;
                    else
                    {
                        uvEdited = new Vector2[] { borders[1], borders[0], borders[2], borders[3] }
                    };
                }
            }
            else
            {
                // Vector2[] uvs = new Vector2[] { new Vector2(0.0f,0.0f), new Vector2(1, 1), new Vector2(1, 0), new Vector2(0, 1)};
                uvEdited = new Vector2[] { borders[0], borders[2], borders[3], borders[1] };
            }
        }
        else
        {
            for (int i = 0; i < uvEdited.Length; i++)
            {
                uvEdited[i] = new Vector2(uvEdited[i].x % piece, uvEdited[i].y % piece);     // относительное положение в собственной текстуре
                uvEdited[i] = new Vector2(borders[0].x + uvEdited[i].x, borders[0].y + uvEdited[i].y);
            }
        }
        quad.uv = uvEdited;

        if (illumination >= 1 - p / 2f)
        {
            return(metal_material);
        }
        else
        {
            // проверка на darkness в самом начале функции
            int pos = (int)(illumination / p);
            if (illumination - pos * p > p / 2f)
            {
                pos++;
            }
            if (pos >= MAX_MATERIAL_LIGHT_DIVISIONS)
            {
                return(metal_material);
            }
            else
            {
                if (metal_illuminated[pos] == null)
                {
                    metal_illuminated[pos] = new Material(metal_material);
                    metal_illuminated[pos].SetFloat("_Illumination", p * (pos + 1));
                }
                return(metal_illuminated[pos]);
            }
        }
    }
Пример #7
0
        public static IScene ParseFile(string filePath, int imageWidth, int imageHeight)
        {
            var background = new Func <Ray, ColorVector>(ray => new ColorVector(0.0f, 0.0f, 0.0f));
            var lights     = new HitableList();
            var world      = new HitableList();
            var cameraAt   = new Vector3(0.0f, 0.0f, 0.0f);
            var cameraFrom = new Vector3(0.0f, 0.0f, 0.0f);
            var cameraUp   = new Vector3(0.0f, 0.0f, 0.0f);

            var lookingFor = LookingFor.Instruction;

            IMaterial currentMaterial = new LambertianMaterial(new ColorTexture(0.0f, 0.0f, 0.0f));

            var polyVectors        = new List <Vector3>();
            var currentItemCounter = 0;

            var lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                var split = line.Split(' ', '\t');

                switch (lookingFor)
                {
                case LookingFor.Instruction:
                {
                    var instruction = split[0];

                    if (instruction == "b")
                    {
                        // background color
                        background = ray => new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    }
                    else if (instruction == "v")
                    {
                        // viewpoint location
                        lookingFor = LookingFor.ViewpointFrom;
                    }
                    else if (instruction == "l")
                    {
                        // positional light
                        //var colorVector = split.Length == 7
                        //                    ? new ColorVector(
                        //                      float.Parse(split[4]),
                        //                      float.Parse(split[5]),
                        //                      float.Parse(split[6]))
                        //                    : new ColorVector(7.0f, 7.0f, 7.0f);
                        var colorVector = new ColorVector(7.0f, 7.0f, 7.0f);
                        var sphere      = new Sphere(
                            new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                            1.5f,
                            new DiffuseLight(new ColorTexture(colorVector)));
                        lights.Add(sphere);
                        world.Add(sphere);
                    }
                    else if (instruction == "f")
                    {
                        // println!("reading f: {}", num);
                        // object material properties
                        // "f" red green blue Kd Ks Shine T index_of_refraction
                        // Kd Diffuse component
                        // Ks Specular
                        // Shine Phong cosine power for highlights
                        // T Transmittance (fraction of contribution of the transmitting ray).
                        // Usually, 0 <= Kd <= 1 and 0 <= Ks <= 1, though it is not required that Kd + Ks = 1. Note that transmitting objects (T > 0) are considered to have two sides for algorithms that need these (normally, objects have one side).
                        // todo: i don't think i'm assigning the correct values into my solidmaterial yet
                        //currentMaterial = new SolidMaterial(
                        //  0.0f, // kAmbient
                        //  float.Parse(split[4]),  // kDiffuse
                        //  float.Parse(split[5]),  // kSpecular
                        //  float.Parse(split[7]),  // kReflection
                        //  float.Parse(split[8]),  // kTransparent
                        //  float.Parse(split[8]),  // refraction    -- todo: which is which here?
                        //  float.Parse(split[6]),  // gloss
                        //  new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))
                        //);
                        // todo: need to look at diffuse/specular/reflection/transparent and pick an appropriate material for it...
                        //currentMaterial = new LambertianMaterial(
                        //  new ColorTexture(
                        //    new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))));
                        if (float.Parse(split[5]) > 0.01)
                        {
                            currentMaterial = new MetalMaterial(
                                new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                                1.5f);
                        }
                        else
                        {
                            currentMaterial = new LambertianMaterial(
                                new ColorTexture(
                                    new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))));
                        }
                    }
                    else if (instruction == "c")
                    {
                        // cone or cylinder
                    }
                    else if (instruction == "s")
                    {
                        // sphere
                        world.Add(
                            new Sphere(
                                new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                                float.Parse(split[4]),
                                currentMaterial));
                    }
                    else if (instruction == "p")
                    {
                        // polygon
                        currentItemCounter = int.Parse(split[1]);
                        polyVectors        = new List <Vector3>();
                        lookingFor         = LookingFor.Polygon;
                    }
                    else if (instruction == "pp")
                    {
                        // polygon patch
                    }
                    else if (instruction == "#")
                    {
                        // comment
                    }
                }
                break;

                case LookingFor.Polygon:
                {
                    if (currentItemCounter > 0)
                    {
                        currentItemCounter--;
                        polyVectors.Add(new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])));
                    }

                    if (currentItemCounter == 0)
                    {
                        if (polyVectors.Count >= 3)
                        {
                            var firstVert = polyVectors[0];
                            var prevVert  = polyVectors[1];
                            var thisVert  = polyVectors[2];
                            world.Add(
                                new Triangle(
                                    new List <Vector3>
                                {
                                    firstVert,
                                    prevVert,
                                    thisVert
                                },
                                    currentMaterial));

                            for (var i = 3; i < polyVectors.Count; i++)
                            {
                                prevVert = thisVert;
                                thisVert = polyVectors[i];
                                world.Add(
                                    new Triangle(
                                        new List <Vector3>
                                    {
                                        firstVert,
                                        prevVert,
                                        thisVert
                                    },
                                        currentMaterial));
                            }
                        }

                        lookingFor = LookingFor.Instruction;
                    }
                }
                break;

                case LookingFor.ViewpointFrom:
                {
                    cameraFrom = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointAt;
                }
                break;

                case LookingFor.ViewpointAt:
                {
                    cameraAt   = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointUp;
                }
                break;

                case LookingFor.ViewpointUp:
                {
                    cameraUp   = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointAngle;
                }
                break;

                case LookingFor.ViewpointAngle:
                {
                    // todo: implement
                    lookingFor = LookingFor.ViewpointHither;
                }
                break;

                case LookingFor.ViewpointHither:
                {
                    // todo: implement
                    lookingFor = LookingFor.ViewpointResolution;
                }
                break;

                case LookingFor.ViewpointResolution:
                {
                    //resolutionX = int.Parse(split[1]);
                    //resolutionY = int.Parse(split[2]);

                    lookingFor = LookingFor.Instruction;
                }
                break;
                }
            }

            return(new NffParserScene(
                       new Camera(
                           cameraFrom,
                           cameraAt,
                           cameraUp,
                           50.0f,
                           Convert.ToSingle(imageWidth) / Convert.ToSingle(imageHeight),
                           0.0f,
                           10.0f),
                       new BvhNode(world, 0.0f, 1.0f),
                       lights,
                       background));
        }