- Home /
Best way to make reflective Pro water receive a spotlight cookie?
I need my flashlight beam (and cookie) to not stop at the water's edge--doesn't look natural. (Pro reflective water; target is Mac and PC standalone.)
What's the best solution? I'm guessing I need another plane situated just above the water. If so, what kind of shader would make the plane invisible but let it receive the spotlight's beam?
Or is there another way?
Thanks for any ideas.
Shadows/Lighting work using the "depth buffer". You can't both have transparency and shadow casting/receiving ability AFAI$$anonymous$$
Answer by Morgan · Aug 11, 2013 at 11:04 AM
Thanks; that includes transparency done by adding the color value to what's behind?
The answer I've come up with is a fake cookie (a standard quad rotated 90 degrees on X) hovering just above the water. It looks pretty good, at least in my situation! Maybe a shader wizard could come up with something more elegant.
I considered flipping the fake face-down (and lifting it off the surface a bit more) so the player doesn't see it directly--only its reflection. A hacky way to make the cookie respond to the wave movements--but it seemed like too much movement; it felt like a reflection and not light cast on the surface. So I just left it face-up and gave it enough transparency that the rippling water shows through, it actually looks as though it's rippling too. (Use a soft/blurry cookie for best results.)
Note that a simple quad can't accurately create the precise effect of a spotlight on the surface: a spotlight is a cone, and the cookie should land distorted like a trapezoid, with the far end bigger. So this effect here is more accurate for a cylindrical light beam, but in practice it still looks good. It DOES stretch as you shine the beam farther away, but not in a trapezoidal way. (To do the job better would require manipulating the quad's vertices or maybe some transformation matrix. Putting my brain through that math wasn't worth it!)
Also, you may want to add horizontal falloff (if your fog isn't enough) since the cookie should get weaker with distance. This script has the beginnings of that, but the alpga gets weaker with VERTICAL distance, since in my case I'm approaching the water from the sky above, not traveling across the surface as in most games.
Here's my script in case it helps anyone tackle cookies on water:
#pragma strict
//Fake cookie example by Morgan Adams - cast a spotlight cookie onto reflective water or other non-cookie-compatible flat surface
//(Put this script on any object--doesn't matter. Put the cookie and its "holder" anywhere at scene root.)
//Use shader Particles/Additive for cookie; adjust alpha to set max cookie strength
var lamp : Transform; //The spotlight
var cookie : GameObject; //The quad for the fake cookie (standard quad rotated 90 degrees on X to lie flat)
var cookieFalloff : float; //Max visible distance (in this example the alpha falloff is VERTICAL; most applications should be tweaked for a falloff into the horizontal distance)
var holder : GameObject; //Empty GameObject - make the cookie a child of this
var waterBoundary : Transform; //The reflective surface, or any GameObject at that vertical position
private var waterOffset : float = .001; //Raise cookie above surface to prevent plane-fighting
private var waterHeight : float;
private var cookieColor : Color;
private var cookieAlpha : float;
function Start() {
waterHeight = waterBoundary.position.y;
cookieColor = cookie.renderer.material.GetColor("_TintColor");
cookieAlpha = cookieColor.a; //Max alpha as pre-set in material
}
function Update () {
holder.transform.position = Vector3( lamp.position.x, waterHeight+waterOffset, lamp.position.z );
holder.transform.eulerAngles.y = lamp.eulerAngles.y;
cookie.transform.localPosition.z = -( Mathf.Abs(lamp.position.y-waterHeight) / Mathf.Tan(Mathf.PI - lamp.eulerAngles.x *Mathf.PI/180) );
var distanceFactor = Mathf.Abs(lamp.position.y-waterHeight)/2;
var angleFactor = cookie.transform.localPosition.z/2;
cookie.transform.localScale = Vector3( distanceFactor+angleFactor, .5+distanceFactor+angleFactor, distanceFactor+angleFactor );
cookieColor.a = cookieAlpha * (1 - Mathf.Min(1, distanceFactor/cookieFalloff)); //Alpha falloff
cookie.renderer.material.SetColor ("_TintColor",cookieColor);
}
Your answer
Follow this Question
Related Questions
Reflective surfaces 0 Answers
Top perspective 2D water 0 Answers
Blend Cubemaps in reflection probe 1 Answer