Пример #1
0
    // Determines the different lighting contributions on a pixel in the scene based on the type of light being processed.
    private Color LightTrace(ObjectRayTracingInfo objectInfo, Light light, Vector3 rayHitPosition, Vector3 surfaceNormal, Vector3 rayDirection)
    {
        Vector3 lightDirection;
        float   lightDistance, lightContribution, dotDirectionNormal;

        if (light.type == LightType.Directional)
        {
            lightContribution = 0;
            lightDirection    = -light.transform.forward;

            // Determine the angle that the light reflects of the surface.
            dotDirectionNormal = Vector3.Dot(lightDirection, surfaceNormal);
            if (dotDirectionNormal > 0)
            {
                // Returns the colour black if the hit position is in shadow.
                if (Physics.Raycast(rayHitPosition, lightDirection, maximumRaycastDistance))
                {
                    return(Color.black);
                }

                lightContribution += CalculateLightContribution(objectInfo, dotDirectionNormal, rayDirection, surfaceNormal, light);
            }

            return(light.color * light.intensity * lightContribution);
        }
        else if (light.type == LightType.Spot)
        {
            lightContribution  = 0;
            lightDirection     = (light.transform.position - rayHitPosition).normalized;
            dotDirectionNormal = Vector3.Dot(lightDirection, surfaceNormal);
            lightDistance      = Vector3.Distance(rayHitPosition, light.transform.position);

            // Ensure the light is within range of the object and the angle of incidence positive.
            if (lightDistance < light.range && dotDirectionNormal > 0f)
            {
                float dotDirectionLight = Vector3.Dot(lightDirection, -light.transform.forward);

                // Ensure the object being lit falls within the spot light's radius.
                if (dotDirectionLight > (1 - light.spotAngle / 180f))
                {
                    // Returns the colour black if the hit position is in shadow.
                    if (Physics.Raycast(rayHitPosition, lightDirection, maximumRaycastDistance))
                    {
                        return(Color.black);
                    }

                    lightContribution += CalculateLightContribution(objectInfo, dotDirectionNormal, rayDirection, surfaceNormal, light);
                }
            }

            if (lightContribution == 0)
            {
                return(Color.black);
            }

            return(light.color * light.intensity * lightContribution);
        }

        return(Color.black);
    }
Пример #2
0
    public float Phong(ObjectRayTracingInfo _objectInfo, Vector3 _rayDirection, Vector3 _hitSurfaceNormal)
    {
        float   reflect        = 2.0f * Vector3.Dot(_rayDirection, _hitSurfaceNormal);
        Vector3 phongDirection = _rayDirection - reflect * _hitSurfaceNormal;
        float   phongTerm      = Max(Vector3.Dot(phongDirection, _rayDirection), 0f);

        return(phongTerm - _objectInfo.reflectiveCoefficient * Mathf.Pow(phongTerm, _objectInfo.phongPower) * _objectInfo.phongCoefficient);
    }
Пример #3
0
    // Calculate the Phong reflection term.
    private float Phong(ObjectRayTracingInfo objectInfo, Vector3 rayDirection, Vector3 hitSurfaceNormal)
    {
        float   reflect        = 2.0f * Vector3.Dot(rayDirection, hitSurfaceNormal);
        Vector3 phongDirection = rayDirection - reflect * hitSurfaceNormal;
        float   phongTerm      = Max(Vector3.Dot(phongDirection, rayDirection), 0f);

        phongTerm = objectInfo.reflectiveCoefficient * Mathf.Pow(phongTerm, objectInfo.phongPower) * objectInfo.phongCoefficient;
        return(phongTerm);
    }
Пример #4
0
    public Color LightTrace(ObjectRayTracingInfo _objectInfo, Light _light, Vector3 _rayHitPosition, Vector3 _surfaceNormal, Vector3 _rayDirection)
    {
        Vector3 lightDirection;
        float   lightDistance, lightContribution, dotDirectionNormal;

        if (_light.type == LightType.Directional)
        {
            lightContribution = 0;
            lightDirection    = -_light.transform.forward;
            // ver angulo da luz
            dotDirectionNormal = Vector3.Dot(lightDirection, _surfaceNormal);
            if (dotDirectionNormal > 0)
            {
                // retorna a sombra se tiver batido nela
                if (Physics.Raycast(_rayHitPosition, lightDirection, maximumRaycastDistance))
                {
                    return(Color.black);
                }
                lightContribution += CalculateLightContribution(_objectInfo, dotDirectionNormal, _rayDirection, _surfaceNormal, _light);
            }
            return(_light.color * _light.intensity * lightContribution);
        }
        else if (_light.type == LightType.Spot)
        {
            lightContribution  = 0;
            lightDirection     = (_light.transform.position - _rayHitPosition).normalized;
            dotDirectionNormal = Vector3.Dot(lightDirection, _surfaceNormal);
            lightDistance      = Vector3.Distance(_rayHitPosition, _light.transform.position);
            // ver se a luz esta no range e como ela ta incidindo.
            if (lightDistance < _light.range && dotDirectionNormal > 0f)
            {
                float dotDirectionLight = Vector3.Dot(lightDirection, -_light.transform.forward);
                // ver se o objeto esta sendo incidido
                if (dotDirectionLight > (1 - _light.spotAngle / 180f))
                {
                    // se acertar a sombra devolve ela
                    if (Physics.Raycast(_rayHitPosition, lightDirection, maximumRaycastDistance))
                    {
                        return(Color.black);
                    }
                    lightContribution += CalculateLightContribution(_objectInfo, dotDirectionNormal, _rayDirection, _surfaceNormal, _light);
                }
            }

            if (lightContribution == 0)
            {
                return(Color.black);
            }
            return(_light.color * _light.intensity * lightContribution);
        }
        return(Color.black);
    }
Пример #5
0
    public Color HandleLights(ObjectRayTracingInfo _objectInfo, Vector3 _hitPosition, Vector3 _normal, Vector3 _direction)
    {
        Color lightColour = RenderSettings.ambientLight;

        for (int i = 0; i < allLightsInScene.Length; i++)
        {
            if (allLightsInScene[i].enabled)
            {
                lightColour += LightTrace(_objectInfo, allLightsInScene[i], _hitPosition, _normal, _direction);
            }
        }
        return(lightColour);
    }
Пример #6
0
    // Handles the light reflections in the scene.
    private Color HandleLights(ObjectRayTracingInfo objectInfo, Vector3 rayHitPosition, Vector3 surfaceNormal, Vector3 rayDirection)
    {
        Color lightColour = RenderSettings.ambientLight;

        for (int i = 0; i < lights.Length; i++)
        {
            if (lights[i].enabled)
            {
                lightColour += LightTrace(objectInfo, lights[i], rayHitPosition, surfaceNormal, rayDirection);
            }
        }

        return(lightColour);
    }
Пример #7
0
    // Calculate the Blinn-Phong reflection term.
    private float BlinnPhong(ObjectRayTracingInfo objectInfo, Light light, Vector3 rayDirection, Vector3 hitSurfaceNormal)
    {
        Vector3 blinnDirection = -light.transform.forward - rayDirection;
        float   temp           = Mathf.Sqrt(Vector3.Dot(blinnDirection, blinnDirection));

        if (temp > 0f)
        {
            blinnDirection = (1f / temp) * blinnDirection;
            float blinnTerm = Max(Vector3.Dot(blinnDirection, hitSurfaceNormal), 0f);
            blinnTerm = objectInfo.reflectiveCoefficient * Mathf.Pow(blinnTerm, objectInfo.blinnPhongPower) * objectInfo.blinnPhongCoefficient;
            return(blinnTerm);
        }
        return(0f);
    }
Пример #8
0
    public float BlinnPhong(ObjectRayTracingInfo _objectInfo, Vector3 _rayDirection, Vector3 _hitSurfaceNormal, Light _lightThatHitted)
    {
        Vector3 blinnDirection = -_lightThatHitted.transform.forward - _rayDirection;
        float   temp           = Mathf.Sqrt(Vector3.Dot(blinnDirection, blinnDirection));

        if (temp > 0f)
        {
            blinnDirection = (1f / temp) * blinnDirection;
            float blinnTerm = Max(Vector3.Dot(blinnDirection, _hitSurfaceNormal), 0f);
            blinnTerm = _objectInfo.reflectiveCoefficient * Mathf.Pow(blinnTerm, _objectInfo.blinnPhongPower) * _objectInfo.blinnPhongCoefficient;
            return(blinnTerm);
        }
        return(0f);
    }
Пример #9
0
    // Determines the overall colour of the pixel at the location of the ray collision.
    private Color DetermineColour(Ray ray, Color positionColour, int currentIteration)
    {
        if (currentIteration < maximumIterations)
        {
            RaycastHit hit;

            // Check the ray intersects a collider.
            if (Physics.Raycast(ray, out hit, maximumRaycastDistance))
            {
                // Determine the basic material colour of the pixel.
                Material objectMaterial = hit.collider.gameObject.GetComponent <Renderer>().material;
                if (objectMaterial.mainTexture)
                {
                    Texture2D mainTexture = objectMaterial.mainTexture as Texture2D;
                    positionColour += mainTexture.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y);
                }
                else
                {
                    positionColour += objectMaterial.color;
                }

                ObjectRayTracingInfo objectInfo = hit.collider.gameObject.GetComponent <ObjectRayTracingInfo>();
                Vector3 hitPosition             = hit.point + hit.normal * 0.0001f;

                positionColour += HandleLights(objectInfo, hitPosition, hit.normal, ray.direction);

                // Solve reflection pixel colour by casting a new reflection ray.
                if (objectInfo.reflectiveCoefficient > 0f)
                {
                    float reflect = 2.0f * Vector3.Dot(ray.direction, hit.normal);
                    Ray   newRay  = new Ray(hitPosition, ray.direction - reflect * hit.normal);
                    positionColour += objectInfo.reflectiveCoefficient * DetermineColour(newRay, positionColour, ++currentIteration);
                }

                // Solve transparent pixels by casting a ray from the hit point past the transparent object.
                if (objectInfo.transparentCoefficient > 0f)
                {
                    Ray newRay = new Ray(hit.point - hit.normal * 0.0001f, ray.direction);
                    positionColour += objectInfo.transparentCoefficient * DetermineColour(newRay, positionColour, ++currentIteration);
                }
            }
        }
        return(positionColour);
    }
Пример #10
0
 public Color ColorOfPixel(Ray _ray, Color _defaultColor, int _currentIteration)
 {
     if (_currentIteration < maximumIterations)
     {
         RaycastHit hit;
         // ver se colidiu.
         if (Physics.Raycast(_ray, out hit, maximumRaycastDistance))
         {
             // pegar a cor basica do objeto.
             Material objectMaterial = hit.collider.gameObject.GetComponent <Renderer>().material;
             //pegar textura
             if (objectMaterial.mainTexture)
             {
                 Texture2D mainTexture = objectMaterial.mainTexture as Texture2D;
                 _defaultColor += mainTexture.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y);
             }
             else
             {
                 //pegar cor
                 _defaultColor += objectMaterial.color;
             }
             //pegar info do objeto
             ObjectRayTracingInfo objectInfo = hit.collider.gameObject.GetComponent <ObjectRayTracingInfo>();
             Vector3 hitPosition             = hit.point + hit.normal * 0.0001f;
             _defaultColor += HandleLights(objectInfo, hitPosition, hit.normal, _ray.direction);
             // se tiver reflexao castar um novo raio
             if (objectInfo.reflectiveCoefficient >= 0f)
             {
                 float reflect = 2.0f * Vector3.Dot(_ray.direction, hit.normal);
                 Ray   newRay  = new Ray(hitPosition, _ray.direction - reflect * hit.normal);
                 _defaultColor += objectInfo.reflectiveCoefficient * ColorOfPixel(newRay, _defaultColor, ++_currentIteration);
             }
             // transparente, castar um novo raio baseado nela
             if (objectInfo.transparentCoefficient > 0f)
             {
                 Ray newRay = new Ray(hit.point - hit.normal * 0.0001f, _ray.direction);
                 _defaultColor += objectInfo.transparentCoefficient * ColorOfPixel(newRay, _defaultColor, ++_currentIteration);
             }
         }
     }
     return(_defaultColor);
 }
Пример #11
0
    public float CalculateLightContribution(ObjectRayTracingInfo _objectInfo, float _dotDirectionNormal, Vector3 _rayDirection, Vector3 _surfaceNormal, Light _light)
    {
        float lightContribution = 0;

        if (_objectInfo.lambertCoefficient > 0)
        {
            lightContribution += _objectInfo.lambertCoefficient * _dotDirectionNormal;
        }
        if (_objectInfo.reflectiveCoefficient > 0)
        {
            if (_objectInfo.phongCoefficient > 0)
            {
                lightContribution += Phong(_objectInfo, _rayDirection, _surfaceNormal);
            }
            if (_objectInfo.blinnPhongCoefficient > 0)
            {
                lightContribution += BlinnPhong(_objectInfo, _rayDirection, _surfaceNormal, _light);
            }
        }
        return(lightContribution);
    }
Пример #12
0
    // Calculate the light contribuation on a specific object hit point and thus pixel location in the scene.
    private float CalculateLightContribution(ObjectRayTracingInfo objectInfo, float dotDirectionNormal, Vector3 rayDirection, Vector3 surfaceNormal, Light light)
    {
        float lightContribution = 0;

        if (objectInfo.lambertCoefficient > 0)
        {
            lightContribution += objectInfo.lambertCoefficient * dotDirectionNormal;
        }

        if (objectInfo.reflectiveCoefficient > 0)
        {
            if (objectInfo.phongCoefficient > 0)
            {
                lightContribution += Phong(objectInfo, rayDirection, surfaceNormal);
            }

            if (objectInfo.blinnPhongCoefficient > 0)
            {
                lightContribution += BlinnPhong(objectInfo, light, rayDirection, surfaceNormal);
            }
        }

        return(lightContribution);
    }