Ejemplo n.º 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);
    }
Ejemplo n.º 2
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);
    }