Example #1
0
    public Color CalcPixelColor(ref long seed, ref int maxDepth, int x, int y, PixelDebugData debug)
    {
        if (debug != null)
        {
            debug.Points.Add(Origin);
        }

        Color accumulateColor = Color.black;
        int   c = debug == null ? AntiAliasRayCount : 1;

        for (int i = 0; i < c; ++i)
        {
            var offsetx = (debug == null ? SimpleRandom.RandNorm(ref seed) : 0.5f) * StepX;
            var offsety = (debug == null ? SimpleRandom.RandNorm(ref seed) : 0.5f) * StepY;
            var dir     = new Vector4(StartX + x * StepX + offsetx, StartY + y * StepY + offsety, 1, 0);
            var dir2    = CameraLocal2World * dir;
            Ray ray     = new Ray(Origin, dir2.normalized);
            accumulateColor += TraceScene(ref seed, ref maxDepth, ray, 0, debug);
        }
        Color col = accumulateColor / c;

        if (GammarCorrection)
        {
            col.r = Mathf.Sqrt(col.r);
            col.g = Mathf.Sqrt(col.g);
            col.b = Mathf.Sqrt(col.b);
        }
        col.a = 1;
        return(col);
    }
Example #2
0
    private Color TraceScene(ref long seed, ref int maxDepth, Ray ray, int depth, PixelDebugData debug)
    {
        HitRecord hit = RaycastScene(ray);

        //HitRecord hit = Scene.RayCast(ray);
        if (debug != null)
        {
            if (hit.t > 0)
            {
                debug.Points.Add(hit.Point);
                debug.DebugText += ("Hit " + hit.Point.ToString() + " " + hit.Normal.ToString() + "\n");
            }
            else
            {
                debug.Points.Add(ray.origin + ray.direction * 100);
                debug.DebugText += "Miss\n";
            }
        }
        Color col = new Color(0, 0, 0, 0);

        if (hit.t > 0 && depth < 20)
        {
            maxDepth = depth > maxDepth ? depth : maxDepth;
            //if (depth > 18)
            //{
            //    depthOverflow = true;
            //}
            var N = hit.Normal;
            var C = (debug == null && depth < 3) ? ScatterRayCount : 1;
            int c = 0;
            for (int i = 0; i < C; ++i)
            {
                Color atten;
                Ray   rayNext;
                if (hit.Material.Scatter(debug, ref seed, ray, ref hit, out atten, out rayNext))
                {
                    col += atten * TraceScene(ref seed, ref maxDepth, rayNext, depth + 1, debug);
                    c   += 1;
                }
            }
            if (c == 0)
            {
                col = Color.Lerp(Color0, Color1, 0.5f + ray.direction.y);
            }
            else
            {
                col = col / c;
            }
        }
        else
        {
            col = Color.Lerp(Color0, Color1, 0.5f + ray.direction.y);
        }
        if (debug != null)
        {
            debug.DebugText += (" Color:" + col.ToString() + "\n");
        }
        return(col);
    }
Example #3
0
    public bool Scatter(PixelDebugData debug, ref long seed, Ray rayIn, ref HitRecord hit, out Color atten, out Ray scattered)
    {
        switch (MatType)
        {
        case RayTracingMaterialType.Lambert:
        {
            Vector3 dir = hit.Normal * 1.0001f;
            if (debug == null)
            {
                dir += SimpleRandom.RandomInsideUnitSphere(ref seed);
            }
            Ray rayOut = new Ray();
            rayOut.origin    = hit.Point;
            rayOut.direction = Vector3.Normalize(dir);
            scattered        = rayOut;
            atten            = Albedo;
            return(true);
        }

        case RayTracingMaterialType.Metal:
        {
            Vector3 dir    = Reflect(rayIn.direction, hit.Normal);
            Ray     rayOut = new Ray();
            rayOut.origin    = hit.Point;
            rayOut.direction = Vector3.Normalize(dir);
            scattered        = rayOut;
            atten            = Albedo;
            return(Vector3.Dot(rayOut.direction, hit.Normal) > 0);
        }

        case RayTracingMaterialType.Dielectric:
        {
            Vector3 N = hit.Normal;
            Vector3 R = Reflect(rayIn.direction, N);
            atten = Color.white;
            float ni_over_nt = Mathf.Max(0.1f, RefractionIndex);
            if (Vector3.Dot(rayIn.direction, N) > 0)
            {
                // Ray travel through inside
                N = -N;
            }
            else
            {
                // Ray comming from outside
                ni_over_nt = 1.0f / ni_over_nt;
            }
            Vector3 refracted;
            float   reflect_prob = 1.0f;
            if (Refract(rayIn.direction, N, ni_over_nt, out refracted))
            {
                reflect_prob = Schlick(Vector3.Dot(N, -rayIn.direction), RefractionIndex);
            }
            if (SimpleRandom.RandNorm(ref seed) < reflect_prob)
            {
                scattered = new Ray(hit.Point, R);
            }
            else
            {
                scattered = new Ray(hit.Point, refracted);
            }
            return(true);
        }
        }
        atten     = Color.black;
        scattered = new Ray();
        return(false);
    }
    private void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 400, 26), "UpdateTexture"))
        {
            _CurrentJob = CreateJob();

            int size   = Width * Height;
            var handle = _CurrentJob.Schedule(Width * Height, Width);
            JobHandle.ScheduleBatchedJobs();
            handle.Complete();
            //_CurrentJob.Run(size);

            Color32[] pixels = _CurrentJob.OutputColors.ToArray();
            if (DebugX > 0 && DebugY > 0 && DebugX < _CurrentJob.Width && DebugY < _CurrentJob.Height)
            {
                int x = DebugX;
                int y = DebugY;
                //for (int y = 0; y < Height; ++y)
                //{
                //    for (int x = 0; x < Width; ++x)
                //    {
                _Debug = new PixelDebugData();
                long seed      = _CurrentJob.RandomSeeds[y * Width + x];
                int  maxDepth2 = 0;
                _CurrentJob.CalcPixelColor(ref seed, ref maxDepth2, x, y, _Debug);
                pixels[y * _CurrentJob.Width + x] = Color.red;
                //if (_CurrentJob.depthOverflow)
                //{
                //    x = Width;
                //    y = Height;
                //}
                //    }
                //}
            }

            if (OutputTexture)
            {
                if (OutputTexture.width != _CurrentJob.Width || OutputTexture.height != _CurrentJob.Height)
                {
                    Object.Destroy(OutputTexture);
                }
            }
            if (!OutputTexture)
            {
                OutputTexture = new Texture2D(_CurrentJob.Width, _CurrentJob.Height);

                if (Preview != null)
                {
                    Preview.material.mainTexture = OutputTexture;
                }
            }
            OutputTexture.SetPixels32(pixels);
            OutputTexture.Apply();

            if (DepthTexture)
            {
                if (DepthTexture.width != _CurrentJob.Width || DepthTexture.height != _CurrentJob.Height)
                {
                    Object.Destroy(DepthTexture);
                }
            }
            if (!DepthTexture)
            {
                DepthTexture = new Texture2D(_CurrentJob.Width, _CurrentJob.Height);
            }
            Color32[] depthPixels = new Color32[size];
            int       maxDepth    = 0;
            for (int i = 0; i < size; ++i)
            {
                int depth = _CurrentJob.MaxDepth[i] * 13;
                maxDepth       = maxDepth > depth ? maxDepth : depth;
                depthPixels[i] = new Color32((byte)((depth >> 0) & 0xFF), (byte)((depth >> 8) & 0xFF), (byte)((depth >> 16) & 0xFF), 255);
            }
            DepthTexture.SetPixels32(depthPixels);
            DepthTexture.Apply();

            _CurrentJob.Dispose();
            Debug.Log("Max Depth: " + maxDepth);
        }
        //GUI.Label(new Rect(10, 10, 400, 26), "Current Iteration: " + _Iteration);
        if (_Debug != null)
        {
            GUI.TextArea(new Rect(10, 40, 400, 360), _Debug.DebugText);
        }
    }