/**
         * Framework function for debugging.
         * @param    traceObj
         * @private
         */
#if DEBUG
        static void debug(TraceObj traceObj)
        {
            if (debugFunction != null)
            {
                if (traceObj.canPrint)
                {
                    debugFunction(traceObj.toString());
                }
            }

            loggerFunction?.Invoke(traceObj);
        }
示例#2
0
    bool Scatter(ref RaycastHit hit, ref Ray ray, ref TraceObj obj, out Color atten, out Ray scatter, out Color light, ref int rayCount)
    {
        var mat = obj.mat;

        light   = Color.black;
        atten   = default(Color);
        scatter = default(Ray);

        switch (mat.type)
        {
        case MaterialWrap.Type.Lambert:
            var hitpos = hit.point;
            var target = hitpos + hit.normal + Random.insideUnitSphere;
            scatter = new Ray(hitpos, (target - hitpos).normalized);
            atten   = mat.albedo;
            return(true);

        case MaterialWrap.Type.Metal:
            var reflect = Vector3.Reflect(ray.direction, hit.normal);

            scatter = new Ray(hit.point, (reflect
                                          + mat.roughness * Random.insideUnitSphere).normalized); // 随机发射,模拟粗糙的表面
            atten = mat.albedo;

            return(Vector3.Dot(reflect, hit.normal) > 0);

        case MaterialWrap.Type.Dielectric:
            atten = Color.white;
            float   nint;
            Vector3 normal;
            float   cosine;
            if (Vector3.Dot(ray.direction, hit.normal) > 0)
            {
                normal = -hit.normal;
                nint   = mat.ri;
                cosine = mat.ri * Vector3.Dot(ray.direction, hit.normal);
            }
            else
            {
                normal = hit.normal;
                nint   = 1 / mat.ri;
                cosine = -Vector3.Dot(ray.direction, hit.normal);
            }

            float reflProb;

            Vector3 refracted;
            if (Refract(ray.direction, normal, nint, out refracted))
            {
                reflProb = Schlick(cosine, mat.ri);
            }
            else
            {
                reflProb = 1;
            }
            if (Random.Range(0, 1.0f) < reflProb)
            {
                scatter = new Ray(hit.point, Vector3.Reflect(ray.direction, hit.normal));
            }
            else
            {
                scatter = new Ray(hit.point, refracted.normalized);
            }

            break;

        default:
            return(false);
        }
        return(true);
    }