Пример #1
0
    private void Working()
    {
        RTMath.ThreadInitRnd();

        for (int i = 0; i < pIndex; ++i)
        {
            if (IsDestroied)
            {
                return;
            }

            Item  item  = items[i];
            Color color = Color.black;
            for (int s = 0; s < numSamples; ++s)
            {
                float u   = (item.i + RTMath.Rnd01()) / canvasWidth;
                float v   = (item.j + RTMath.Rnd01()) / canvasHeight;
                RTRay ray = cam.GetRay(u, v);
                color += renderer.GetColor(ray, 0);
            }
            color          /= numSamples;
            item.finalColor = color;
            items[i]        = item;
        }

        status = STATUS_COMPLETE;
    }
Пример #2
0
    public override bool Scatter(RTRay ray, HitRecord hit, out Color attenuation, out RTRay scattered)
    {
        attenuation = new Color(1, 1, 1);

        Vector3 outwardN;
        float   ni_over_nt;
        Vector3 refracted;
        float   reflect_prob;
        float   cosine;

        if (Vector3.Dot(ray.direction, hit.n) > 0)
        {
            outwardN   = -hit.n;
            ni_over_nt = refractiveIndex;
            cosine     = Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude;
        }
        else
        {
            outwardN   = hit.n;
            ni_over_nt = 1.0f / refractiveIndex;
            cosine     = -Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude;
        }

        if (RTMath.Refract(ray.direction, outwardN, ni_over_nt, out refracted))
        {
            reflect_prob = RTMath.schlick(cosine, refractiveIndex);
        }
        else
        {
            reflect_prob = 1.0f;
        }

        if (RTMath.Rnd01() < reflect_prob)
        {
            scattered = new RTRay().Set(hit.p, RTMath.Reflect(ray.direction, hit.n));
        }
        else
        {
            scattered = new RTRay().Set(hit.p, refracted);
        }

        return(true);
    }
    protected override void Awake()
    {
        base.Awake();

        numSamples      = 5;
        isScreenSize    = true;
        ppmTexture.sRGB = true;

        scene = new HitableList();

        scene.list.Add(new RTSphere().Set(new Vector3(0, -1000, 0), 1000).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(0.5f, 0.5f, 0.5f))));

        for (int a = -11; a < 11; ++a)
        {
            for (int b = -11; b < 11; ++b)
            {
                float   rnd    = RTMath.Rnd01();
                Vector3 center = new Vector3(a + 0.9f * rnd, 0.2f, b + 0.9f * rnd);
                if ((center - new Vector3(4, 0.2f, 0)).magnitude > 0.9f)
                {
                    if (rnd < 0.6f)
                    {
                        scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(RTMath.Rnd01(), RTMath.Rnd01(), RTMath.Rnd01()))));
                    }
                    else if (rnd < 0.9f)
                    {
                        scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Metal().SetAlbedo <Metal>(new Color(0.5f * (1 + RTMath.Rnd01()), 0.5f * (1 + RTMath.Rnd01()), 0.5f * (1 + RTMath.Rnd01()))).SetFuzz(0.5f * RTMath.Rnd01())));
                    }
                    else
                    {
                        scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Dielectric().SetRefractiveIndex(1.5f)));
                    }
                }
            }
        }

        scene.list.Add(new RTSphere().Set(new Vector3(0, 1, 0), 1).SetMaterial <RTSphere>(new Dielectric().SetRefractiveIndex(1.5f)));
        scene.list.Add(new RTSphere().Set(new Vector3(-4, 1, 0), 1).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(0.4f, 0.2f, 0.1f))));
        scene.list.Add(new RTSphere().Set(new Vector3(4, 1, 0), 1).SetMaterial <RTSphere>(new Metal().SetAlbedo <Metal>(new Color(0.7f, 0.6f, 0.5f)).SetFuzz(0.0f)));
    }
Пример #4
0
    protected virtual void Start()
    {
        int canvasWidth  = isScreenSize ? Screen.width : 200;
        int canvasHeight = isScreenSize ? Screen.height : 100;

        cam = CreateCamera(canvasWidth, canvasHeight);
        ppmTexture.Init(canvasWidth, canvasHeight);

        renderingTasksManager = new RenderingTasksManager();

        int           pixelIndex = 0;
        RenderingTask task       = null;
        int           itemsCount = 0;

        for (int j = 0; j < ppmTexture.Height; ++j)
        {
            for (int i = 0; i < ppmTexture.Width; ++i)
            {
                if (multiThreadRendering)
                {
                    if (itemsCount == 0)
                    {
                        task = new RenderingTask();
                        task.Init(this, cam, ppmTexture.Width, ppmTexture.Height, numSamples);
                        renderingTasksManager.AddTask(task, RenderingTaskCompleteCB);
                    }
                    task.AddItem(i, j, pixelIndex);
                    ++itemsCount;
                    if (itemsCount == RenderingTask.SIZE)
                    {
                        itemsCount = 0;
                    }
                    ++pixelIndex;
                }
                else
                {
                    Color color = Color.black;
                    for (int s = 0; s < numSamples; ++s)
                    {
                        float u = (i + RTMath.Rnd01()) / ppmTexture.Width;
                        float v = (j + RTMath.Rnd01()) / ppmTexture.Height;

                        RTRay ray = cam.GetRay(u, v);
                        color += GetColor(ray, 0);
                    }
                    color /= numSamples;
                    ppmTexture.WriteAPixel(color);
                }
            }
        }

        if (!multiThreadRendering)
        {
            ppmTexture.Complete();
            RenderingComplete();
        }
        else
        {
            renderingTasksManager.Start();
        }
    }