Search Unity

REALISTIC LENS FLARE!! Finally make them appear and disappear instantaneously

Discussion in 'Assets and Asset Store' started by jmsosullivan, May 12, 2011.

  1. jmsosullivan

    jmsosullivan

    Joined:
    Aug 16, 2010
    Posts:
    18
    Attach this script to any lens flare in your scene. It will now appear and disappear instantaneously when occluded by an object or when it's outside of the camera's frustrum. It will also get brighter or dimmer depending on the camera's distance to it. Enjoy!

    Code (csharp):
    1.  //I actually don't know why this works, but it does! Some kind of glitch I presume.
    2.  //For some reason, when the flare is visible to the camera, and you then change it's layer to one that's on its ignore list,
    3.  //the flare will then permanently stay on. (It doesn't work if you do this before the flare is visible; it will just never appear.)
    4.  //By then changing its brightness to zero when it's outside of the camera's frustrum or when it's occluded by a collider,
    5.  //it acts like a more realistic flare.
    6.  //
    7.  //Note that the first time you look at the flare, it will fade in it's usual unrealistic manner, but will change subsequently.
    8.  
    9.  //Coordinates for the right and left hand sides of the screen respectively
    10.  //Change to "1" and "0" if you want the flare to disappear as soon as its invisible to the camera's frustrum.
    11.  private var coord1 = 1.2; 
    12.  private var coord2 = -0.2;
    13.  
    14.  //The strength of the flare relative to it's distance from the camera ("brightness = strength/distance")
    15.  private var strength = 5;
    16.  
    17.  //Simple counter to ensure that the flare is visible for a few frames before the layer is changed
    18.  var count = 0;
    19.  
    20.  function Start()
    21.  {
    22.  //Ensures that the flare's layer isn't part of its ingore list to begin with
    23.  //Change to whatever you want, as long as it's not on the ignore list
    24.  gameObject.layer= Layer.Default;
    25.  }
    26.  
    27.  function Update ()
    28.  {
    29.  var heading: Vector3 = gameObject.transform.position - Camera.main.transform.position;
    30.  var heading2: Vector3 = Camera.main.transform.position -gameObject.transform.position;
    31.  var dist: float = Vector3.Dot(heading, Camera.main.transform.forward);
    32.  var viewPos : Vector3 = Camera.main.WorldToViewportPoint (gameObject.transform.position);
    33.  
    34.  //Turns off the flare when it goes outside of the camera's frustrum
    35.  if( viewPos.x > coord1 || viewPos.x < coord2 || viewPos.y < coord2 || viewPos.y > coord1)
    36.  gameObject.GetComponent(LensFlare).brightness = 0;
    37.  
    38.  //Turns off the flare when it's occluded by a collider.
    39.  else if (Physics.Raycast (gameObject.transform.position, heading2.normalized, Mathf.Clamp(dist,0.01,20)))
    40.  gameObject.GetComponent(LensFlare).brightness = 0;
    41.  
    42.  else
    43.  {
    44.  //Sets the flares brightness to be an inverse function of distance from the camera
    45.  gameObject.GetComponent(LensFlare).brightness = strength/dist;
    46.  if(count<50)
    47.  count = count+1;
    48.  }
    49.  
    50.  //Changes the layer of the flare to be "Transparent FX"
    51.  //Change it to whatever you want as long as you include that layer in your ignore list of the flare
    52.  if(count > 20)
    53.   {
    54.   gameObject.layer= 1;
    55.   }
    56.  }
     
  2. Infeecctteedd

    Infeecctteedd

    Joined:
    Apr 6, 2011
    Posts:
    70
    Wow, thanks a lot! Great stuff.
     
  3. unity3dx

    unity3dx

    Joined:
    Apr 15, 2011
    Posts:
    175
    Was doing an error at compile. Also changed a couple of little things.

    Code (csharp):
    1.  //I actually don't know why this works, but it does! Some kind of glitch I presume.
    2.  //For some reason, when the flare is visible to the camera, and you then change it's layer to one that's on its ignore list,
    3.  //the flare will then permanently stay on. (It doesn't work if you do this before the flare is visible; it will just never appear.)
    4.  //By then changing its brightness to zero when it's outside of the camera's frustrum or when it's occluded by a collider,
    5.  //it acts like a more realistic flare.
    6.  //
    7.  //Note that the first time you look at the flare, it will fade in it's usual unrealistic manner, but will change subsequently.
    8.  
    9.  //Coordinates for the right and left hand sides of the screen respectively
    10.  //Change to "1" and "0" if you want the flare to disappear as soon as its invisible to the camera's frustrum.
    11.  private var coord1 = 1.2; 
    12.  private var coord2 = -0.2;
    13.  
    14.  //The strength of the flare relative to it's distance from the camera ("brightness = strength/distance")
    15. public var strength = 5;
    16.  
    17.  //Simple counter to ensure that the flare is visible for a few frames before the layer is changed
    18.  var count = 0;
    19.  var countmax=10;
    20.  
    21.  function Start()
    22.  {
    23.  //Ensures that the flare's layer isn't part of its ingore list to begin with
    24.  //Change to whatever you want, as long as it's not on the ignore list
    25.     gameObject.layer= 0;
    26.  }
    27.  
    28.  function Update ()
    29.  {
    30.      var heading: Vector3 = gameObject.transform.position - Camera.main.transform.position;
    31.      var heading2: Vector3 = Camera.main.transform.position -gameObject.transform.position;
    32.      var dist: float = Vector3.Dot(heading, Camera.main.transform.forward);
    33.      var viewPos : Vector3 = Camera.main.WorldToViewportPoint (gameObject.transform.position);
    34.      
    35.      //Turns off the flare when it goes outside of the camera's frustrum
    36.      if( viewPos.x > coord1 || viewPos.x < coord2 || viewPos.y < coord2 || viewPos.y > coord1)
    37.      gameObject.GetComponent(LensFlare).brightness = 0;
    38.      
    39.      //Turns off the flare when it's occluded by a collider.
    40.      else if (Physics.Raycast (gameObject.transform.position, heading2.normalized, Mathf.Clamp(dist,0.01,20)))
    41.      gameObject.GetComponent(LensFlare).brightness = 0;
    42.      
    43.      else
    44.      {
    45.      //Sets the flares brightness to be an inverse function of distance from the camera
    46.      gameObject.GetComponent(LensFlare).brightness = strength/dist;
    47.      if(count<countmax)
    48.         count = count+1;
    49.      }
    50.      
    51.      //Changes the layer of the flare to be "Transparent FX"
    52.      //Change it to whatever you want as long as you include that layer in your ignore list of the flare
    53.      if(count > countmax/2)
    54.       {
    55.         gameObject.layer= 1;
    56.       }
    57.  }
    58.  
     
    Last edited: May 13, 2011
  4. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It's never a good idea to base code on glitches, at least not since the Amiga and 8 bit eras. Since things that glitch can get fixed in a unity patch.
     
  5. jmsosullivan

    jmsosullivan

    Joined:
    Aug 16, 2010
    Posts:
    18
    Well hippocoder, we've all been waiting a long time for lens flares to work properly, and have requested a fix several times, but nothing ever came. Also, it might not be ideal to base code on glitches, but if it works it works.
     
  6. jmsosullivan

    jmsosullivan

    Joined:
    Aug 16, 2010
    Posts:
    18
    unity3dx, why were you getting a compile error? I can only see one thing you've changed in the code (the counter), and it doesn't really change anything.

    Actually you're right, I had another script running which allowed you to name your layers "default" etc. In that original code you would get a compiler error. Thanks for pointing it out
     
    Last edited: May 23, 2011
  7. kraemology

    kraemology

    Joined:
    Oct 20, 2010
    Posts:
    20
    Perhaps I'm not understanding, but I'm editing the various exposed variables and still not seeing any discernible variation; nor am I seeing any variation between the lens flare in question and the others around it that do not have the script attached? Any thoughts on the matter?
     
  8. jmsosullivan

    jmsosullivan

    Joined:
    Aug 16, 2010
    Posts:
    18
    Hi kremology. This is a very glitchy method. You have to first make sure that the camera can't see the flare. Then move the camera so that it can. At first, the flare will fade into view as it normally would. However, on each subsequent viewing, it should appear instantaneously.

    I did notice a problem with this though. If the camera is facing away from the flare at a 180 degree angle (so facing directly away from it) it will render the flare immediately, meaning that this method won't work.

    So essentially, you have to position your camera in such a place so that when the level starts, it's in the correct position to use this method. Also, make sure that you have the layers organised correctly as described in the code.

    I know it's not a perfect solution, but until Unity make a seemingly simple fix, it's the best I've got.
     
  9. kraemology

    kraemology

    Joined:
    Oct 20, 2010
    Posts:
    20
    Ah ok, Thanks for the info + the script