예제 #1
0
        public static Color[] CreateColorFromHitRecord(int width, int height)
        {
            var camera      = new RayTraceCamera(Vector3.zero, new Vector3(0f, 0f, -1f), Vector3.up, 90f, 2f, 0f, 1f);
            var colors      = new Color[width * height];
            var hitableList = new HitableList();

            hitableList.List.Add(new Sphere(new Vector3(0, 0, -1), 0.5f, new Lambertian(Color.white)));
            hitableList.List.Add(new Sphere(new Vector3(0, -100.5f, -1), 100f, new Lambertian(Color.white)));
            for (int j = height - 1; j >= 0; j--)
            {
                for (int i = 0; i < width; i++)
                {
                    var color = new Color();
                    for (int s = 0; s < SamplingNumber; s++)
                    {
                        var u = (i + Random.Range(0, 1f)) / width;
                        var v = (j + Random.Range(0, 1f)) / height;
                        var r = camera.GetRay(u, v);
                        color += GetColorFromHitRecord(r, hitableList);
                    }
                    color /= SamplingNumber;
                    colors[i + j * width] = new Color(Mathf.Sqrt(color.r), Mathf.Sqrt(color.g), Mathf.Sqrt(color.b), 1f);
                }
            }

            return(colors);
        }
예제 #2
0
        static HitableList GetHitableListFromScene()
        {
            var hitableList = new HitableList();

            hitableList.List.Add(new Sphere(new Vector3(0f, -1000f, 0f), 1000f, new Lambertian(new Color(0.5f, 0.5f, 0.5f))));
            for (int a = -4; a < 4; a++)
            {
                for (var b = -4; b < 4; b++)
                {
                    var chooseMat = Random.Range(0f, 1f);
                    var center    = new Vector3(a + 0.9f * Random.Range(0f, 1f), 0.2f, b + 0.9f * Random.Range(0f, 1f));

                    if (Vector3.Distance(center, new Vector3(4f, 0.2f, 4f)) > 0.9f)
                    {
                        if (chooseMat < 0.8f)
                        {
                            hitableList.List.Add(new Sphere(center, 0.2f, new Lambertian(GetRandomColor())));
                        }
                        else if (chooseMat < 0.95f)
                        {
                            hitableList.List.Add(new Sphere(center, 0.2f, new Metal(GetRandomMatalColor())));
                        }
                        else
                        {
                            hitableList.List.Add(new Sphere(center, 0.2f, new Dielectirc(1.5f)));
                        }
                    }
                }
            }

            hitableList.List.Add(new Sphere(new Vector3(0f, 1f, 0f), 1f, new Dielectirc(1.5f)));
            hitableList.List.Add(new Sphere(new Vector3(-4f, 1f, 0f), 1f, new Lambertian(new Color(0.4f, 0.2f, 0.5f))));
            hitableList.List.Add(new Sphere(new Vector3(4f, 1f, 0f), 1f, new Metal(new Color(0.7f, 0.6f, 0.5f))));
            return(hitableList);
        }
예제 #3
0
        static HitableList GetHitableListFromSimpleScene()
        {
            var hitableList = new HitableList();

            hitableList.List.Add(new Sphere(new Vector3(0, 0, -1), 0.5f, new Lambertian(new Color(0.8f, 0.3f, 0.3f))));
            hitableList.List.Add(new Sphere(new Vector3(0, -100.5f, -1), 100f, new Lambertian(new Color(0.8f, 0.8f, 0f))));
            hitableList.List.Add(new Sphere(new Vector3(1, 0, -1f), 0.5f, new Metal(new Color(0.8f, 0.6f, 0.2f))));
            hitableList.List.Add(new Sphere(new Vector3(-1, 0, -1f), 0.5f, new Dielectirc(1.2f)));
            return(hitableList);
        }
예제 #4
0
        static Color GetColorFromHitRecord(Ray ray, HitableList list)
        {
            var rec = new HitRecord();

            if (list.Hit(ray, 0.001f, float.MaxValue, ref rec))
            {
                var target = rec.Point + rec.Normal + RayTraceUtility.GetRandomPointInUnitSphere();
                return(0.5f * GetColorFromHitRecord(new Ray(rec.Point, target - rec.Point), list));
            }

            var t = (ray.NormalizedDirection.y + 1f) * 0.5f;

            return((1 - t) * Color.white + t * new Color(0.5f, 0.7f, 1f));
        }
        static Color GetColorForTestMetal(Ray ray, HitableList hitableList, int depth)
        {
            HitRecord record = new HitRecord();

            if (hitableList.Hit(ray, 0.0001f, float.MaxValue, ref record))
            {
                Ray   r           = new Ray(Vector3.zero, Vector3.zero);
                Color attenuation = Color.black;
                if (depth < MAX_SCATTER_TIME && record.material.Scatter(ray, record, ref attenuation, ref r))
                {
                    Color c = GetColorForTestMetal(r, hitableList, depth + 1);
                    return(new Color(c.r * attenuation.r, c.g * attenuation.g, c.b * attenuation.b));
                }

                return(Color.black);
            }
            float t = 0.5f * ray.normalDirection.y + 1f;

            return((1 - t) * new Color(1, 1, 1) + t * new Color(0.5f, 0.7f, 1));
        }
        public static Color[] MakeColors()
        {
            int width  = CreatPNG.WIDTH;
            int height = CreatPNG.HEIGHT;
            //视锥体的左下角、长宽和起始扫射点设定
            Vector3     lowLeftCorner = new Vector3(-2, -1, -1);
            Vector3     horizontal    = new Vector3(4, 0, 0);
            Vector3     vertical      = new Vector3(0, 2, 0);
            Vector3     original      = new Vector3(0, 0, 0);
            int         l             = width * height;
            HitableList hitableList   = new HitableList();

            hitableList.AddHitable(new HitableSphere(new Vector3(0, 0, -1), 0.5f, new Lambert(new Color(0.8f, 0.3f, 0.3f))));
            hitableList.AddHitable(new HitableSphere(new Vector3(0, -100.5f, -1), 100f, new Lambert(new Color(0.8f, 0.8f, 0.0f))));
            hitableList.AddHitable(new HitableSphere(new Vector3(1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.6f, 0.2f))));
            hitableList.AddHitable(new HitableSphere(new Vector3(-1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.8f, 0.8f))));
            Color[] colors = new Color[l];


            for (int j = height - 1; j >= 0; j--)
            {
                for (int i = 0; i < width; i++)
                {
                    Color color = new Color(0, 0, 0);
                    for (int s = 0; s < SAMPLETIMES; s++)
                    {
                        Ray r = new Ray(original,
                                        lowLeftCorner + horizontal * ((j + Random.Range(0, 1f)) / (float)width) +
                                        vertical * ((i + Random.Range(0, 1f)) / (float)height));
                        color += GetColorForTestMetal(r, hitableList, 0);
                    }
                    color /= SAMPLETIMES;
                    //为了使球体看起来更亮,改变gamma值
                    color   = new Color(Mathf.Sqrt(color.r), Mathf.Sqrt(color.g), Mathf.Sqrt(color.b), 1f);
                    color.a = 1f;
                    colors[i + j * width] = color;
                }
            }
            return(colors);
        }
예제 #7
0
        static Color GetColorFromHitRecord(Ray ray, HitableList list, int depth)
        {
            var record = new HitRecord();

            if (list.Hit(ray, 0.001f, float.MaxValue, ref record))
            {
                var scatterdRay = new Ray(Vector3.zero, Vector3.zero);
                var attenuation = Color.black;
                if (depth < MaxDepth && record.Material.Scatter(ray, record, ref attenuation, ref scatterdRay))
                {
                    var c = GetColorFromHitRecord(scatterdRay, list, depth + 1);
                    return(new Color(c.r * attenuation.r, c.g * attenuation.g, c.b * attenuation.b));
                }
                else
                {
                    return(Color.black);
                }
            }

            var t = (ray.NormalizedDirection.y + 1f) * 0.5f;

            return((1 - t) * Color.white + t * new Color(0.5f, 0.7f, 1f));
        }