Пример #1
0
        public static bool Disk(Disk d, Ray3f r, float tMin, float tMax, out HitRecord hit)
        {
            hit = new HitRecord();

            if (Plane(d.Plane, r, tMin, tMax, out hit))
            {
                var offset = (hit.point - d.Plane.Center);
                if (math.dot(offset, offset) <= d.Radius * d.Radius)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        public static bool Plane(Plane p, Ray3f r, float tMin, float tMax, out HitRecord hit)
        {
            hit = new HitRecord();

            const float eps = 0.0001f;

            if (math.abs(math.dot(r.direction, p.Normal)) > eps)
            {
                float t = math.dot((p.Center - r.origin), p.Normal) / math.dot(r.direction, p.Normal);
                if (t > eps)
                {
                    hit.t      = t;
                    hit.point  = PointOnRay(r, t);
                    hit.normal = p.Normal;
                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
        public static bool Scatter(Ray3f ray, HitRecord hit, ref Random rng, NativeArray <float3> fibs, out Ray3f scattered)
        {
            const float epsEscape = 0.002f;

            const float refIdx = 1.5f;

            switch (hit.material.Type)
            {
            case MaterialType.Dielectric: {
                float3 outwardNormal;
                float  nint;
                float3 reflected = math.reflect(ray.direction, hit.normal);
                float  cosine;

                if (math.dot(ray.direction, hit.normal) > 0f)
                {
                    outwardNormal = -hit.normal;
                    nint          = refIdx;
                    cosine        = refIdx * math.dot(ray.direction, hit.normal);
                }
                else
                {
                    outwardNormal = hit.normal;
                    nint          = 1f / refIdx;
                    cosine        = -math.dot(ray.direction, hit.normal);
                }

                float  reflectProb = 1f;
                float3 refracted;
                if (Trace.Refract(ray.direction, outwardNormal, nint, out refracted))
                {
                    reflectProb = Trace.Schlick(cosine, refIdx);
                }

                bool reflect = rng.NextFloat() < reflectProb;

                scattered = new Ray3f(
                    reflect ? hit.point + outwardNormal * epsEscape : hit.point - outwardNormal * epsEscape,
                    reflect ? reflected : refracted
                    );
                return(true);
            }

            case MaterialType.Metal: {
                float3 transmitted = math.reflect(ray.direction, hit.normal);
                transmitted += fibs[rng.NextInt(0, fibs.Length - 1)] * hit.material.Fuzz;
                transmitted  = math.normalize(transmitted);
                scattered    = new Ray3f(hit.point + hit.normal * epsEscape, transmitted);
                if (math.dot(scattered.direction, hit.normal) > 0)
                {
                    return(true);
                }
                return(false);
            }

            case MaterialType.Lambertian:
            default: {
                float3 target      = hit.normal + fibs[rng.NextInt(0, fibs.Length - 1)];
                float3 transmitted = math.normalize(target - hit.point);
                scattered = new Ray3f(hit.point + hit.normal * epsEscape, transmitted);
                return(true);
            }
            }
        }
Пример #4
0
 public static float3 PointOnRay(Ray3f r, float t)
 {
     return(r.origin + r.direction * t);
 }