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!
//I actually don't know why this works, but it does! Some kind of glitch I presume.
//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,
//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.)
//By then changing its brightness to zero when it's outside of the camera's frustrum or when it's occluded by a collider,
//it acts like a more realistic flare.
//
//Note that the first time you look at the flare, it will fade in it's usual unrealistic manner, but will change subsequently.
//Coordinates for the right and left hand sides of the screen respectively
//Change to "1" and "0" if you want the flare to disappear as soon as its invisible to the camera's frustrum.
private var coord1 = 1.2;
private var coord2 = -0.2;
//The strength of the flare relative to it's distance from the camera ("brightness = strength/distance")
private var strength = 5;
//Simple counter to ensure that the flare is visible for a few frames before the layer is changed
var count = 0;
function Start()
{
//Ensures that the flare's layer isn't part of its ingore list to begin with
//Change to whatever you want, as long as it's not on the ignore list
gameObject.layer= Layer.Default;
}
function Update ()
{
var heading: Vector3 = gameObject.transform.position - Camera.main.transform.position;
var heading2: Vector3 = Camera.main.transform.position -gameObject.transform.position;
var dist: float = Vector3.Dot(heading, Camera.main.transform.forward);
var viewPos : Vector3 = Camera.main.WorldToViewportPoint (gameObject.transform.position);
//Turns off the flare when it goes outside of the camera's frustrum
if( viewPos.x > coord1 || viewPos.x < coord2 || viewPos.y < coord2 || viewPos.y > coord1)
gameObject.GetComponent(LensFlare).brightness = 0;
//Turns off the flare when it's occluded by a collider.
else if (Physics.Raycast (gameObject.transform.position, heading2.normalized, Mathf.Clamp(dist,0.01,20)))
gameObject.GetComponent(LensFlare).brightness = 0;
else
{
//Sets the flares brightness to be an inverse function of distance from the camera
gameObject.GetComponent(LensFlare).brightness = strength/dist;
if(count<50)
count = count+1;
}
//Changes the layer of the flare to be "Transparent FX"
//Change it to whatever you want as long as you include that layer in your ignore list of the flare
if(count > 20)
{
gameObject.layer= 1;
}
}
Wow, thanks a lot! Great stuff.
Was doing an error at compile. Also changed a couple of little things.
//I actually don't know why this works, but it does! Some kind of glitch I presume.
//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,
//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.)
//By then changing its brightness to zero when it's outside of the camera's frustrum or when it's occluded by a collider,
//it acts like a more realistic flare.
//
//Note that the first time you look at the flare, it will fade in it's usual unrealistic manner, but will change subsequently.
//Coordinates for the right and left hand sides of the screen respectively
//Change to "1" and "0" if you want the flare to disappear as soon as its invisible to the camera's frustrum.
private var coord1 = 1.2;
private var coord2 = -0.2;
//The strength of the flare relative to it's distance from the camera ("brightness = strength/distance")
public var strength = 5;
//Simple counter to ensure that the flare is visible for a few frames before the layer is changed
var count = 0;
var countmax=10;
function Start()
{
//Ensures that the flare's layer isn't part of its ingore list to begin with
//Change to whatever you want, as long as it's not on the ignore list
gameObject.layer= 0;
}
function Update ()
{
var heading: Vector3 = gameObject.transform.position - Camera.main.transform.position;
var heading2: Vector3 = Camera.main.transform.position -gameObject.transform.position;
var dist: float = Vector3.Dot(heading, Camera.main.transform.forward);
var viewPos : Vector3 = Camera.main.WorldToViewportPoint (gameObject.transform.position);
//Turns off the flare when it goes outside of the camera's frustrum
if( viewPos.x > coord1 || viewPos.x < coord2 || viewPos.y < coord2 || viewPos.y > coord1)
gameObject.GetComponent(LensFlare).brightness = 0;
//Turns off the flare when it's occluded by a collider.
else if (Physics.Raycast (gameObject.transform.position, heading2.normalized, Mathf.Clamp(dist,0.01,20)))
gameObject.GetComponent(LensFlare).brightness = 0;
else
{
//Sets the flares brightness to be an inverse function of distance from the camera
gameObject.GetComponent(LensFlare).brightness = strength/dist;
if(count<countmax)
count = count+1;
}
//Changes the layer of the flare to be "Transparent FX"
//Change it to whatever you want as long as you include that layer in your ignore list of the flare
if(count > countmax/2)
{
gameObject.layer= 1;
}
}
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.
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.
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
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?
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.
Ah ok, Thanks for the info + the script