// 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); }
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); }
// 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); }
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); }
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); }
// 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); }
// 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); }
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); }
// 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); }
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); }
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); }
// 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); }