Exemplo n.º 1
0
    Color TracePath(Ray ray, int depth)
    {
        if (depth >= MaxDepth)
        {
            return(Color.black);  // Bounced enough times.
        }
        SceneRayHit hit = scene.RayCast(ray);

        if (hit == null)
        {
            return(Color.black);  // Nothing was hit.
        }
        Profiler.BeginSample("GetComponent<MeshRenderer");
        Profiler.EndSample();
        Profiler.BeginSample("GetEmissionColor");
        var emittance = hit.HitObj.Emittance;

        Profiler.EndSample();
        // Pick a random direction from here and keep going.
        // This is NOT a cosine-weighted distribution!
        Profiler.BeginSample("RandomUnitVectorInHemisphere");
        var direction = RandomUnitVectorInHemisphereOf(hit.normal);

        Profiler.EndSample();
        Ray newRay = new Ray(hit.point, direction);
        // Recursively trace reflected light sources.
        Color incoming = TracePath(newRay, depth + 1);

        Profiler.BeginSample("LightCal");
        // Probability of the newRay
        float p = 1 / (2 * M_PI);

        // Compute the BRDF for this ray (assuming Lambertian reflection)
        Profiler.BeginSample("Dot");
        float cos_theta = Mathf.Max(0, Vector3.Dot(newRay.direction.normalized, hit.normal.normalized));

        Profiler.EndSample();
        Profiler.BeginSample("GetColor");
        Color BRDF = hit.HitObj.reflectance / M_PI;

        Profiler.EndSample();
        // Apply the Rendering Equation here.
        var finalColor = emittance + (BRDF * incoming * cos_theta / p);

        Profiler.EndSample();
        return(finalColor);
    }
Exemplo n.º 2
0
    public SceneRayHit RayCast(Ray ray)
    {
        SceneRayHit hitObj = new SceneRayHit();

        for (int i = 0; i < SceneObjects.Length; ++i)
        {
            RaycastHit hit;
            if (SceneObjects[i].RayCast(ray, out hit))
            {
                if (hitObj.HitObj == null || hit.distance < hitObj.distance)
                {
                    hitObj.HitObj   = SceneObjects[i];
                    hitObj.normal   = hit.normal;
                    hitObj.point    = hit.point;
                    hitObj.distance = hit.distance;
                }
            }
        }
        return(hitObj.HitObj != null ? hitObj : null);
    }