0
\$\begingroup\$

I know how to check if object is in camera view but how I can check if that object is cover by something elese? In my case I want to turn on or off some effect when I look at light. At this moment my code is straight forward, I have created interface for lightable object with method

public bool isVisibleByCam(Camera cam) {
    if (GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(cam), gameObject.GetComponent<Collider>().bounds)) {
        return true;
    }
    return false;
}

I hope there is better way than checking every object in camera view and comparing distnace between camera.

\$\endgroup\$
  • \$\begingroup\$ Are you talking about something like activating a bloom pass when looking toward lights? Also, the snippet is not very telling; are you already using deferred lighting elsewhere? \$\endgroup\$ – Jon Mar 28 '15 at 0:04
  • \$\begingroup\$ If you are just trying to reduce the N-cost of sorting your scene, you'll want to use a quad- or oct-tree. \$\endgroup\$ – Jon Mar 28 '15 at 0:10
1
\$\begingroup\$

Hello I suggest you use Raycasting to test if the camera is directly pointing to the light source. The ray will go from the camera into the front vector direction, Once you get the RaycastHit, you can check the name, the tag or even use Layer Mask to selectively ignore colliders.

If you want to apply the effect even when the camera is not pointing directly to the light, you can combine the test you are already doing to determine if the light is in view, and then raycast using the transform.LookAt(target) method to get a vector from the camera in the direction of the light. Please note that LookAt will rotate the transform, so do it with a new object that has the same values, or use Quaternion.LookRotation if you prefer.

Lastly you can improve using Vector3.Angle and Vector3.Distance to fine tune when to trigger the effect. Here is how you get the angle and distance assuming you have an array of all the lights on the view:

    for( int i = 0; i < lightObjects.Length; i++)
    {
        Vector3 targetLine = lightObjects[i].transform.position - camera.transform.position; //Obtain the vector from camera to Target light
        float distance = targetLine.magnitude;
        float angle = Vector3.Angle (camera.transform.forward, targetLine); //Get the Angle between camera forwward and targetDir
        if ( (distance < shortDistance && angle < 30) || 
                    (distance < mediumDistance && angle < 15) || (distance < longDistance && angle < 5f) )
        {
            Debug.Log("Apply effect on light " + lightObjects[i].name);
            Debug.Log("Angle: " + angle.ToString () + " Distance: " + distance.ToString());
        }
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.