Freedom Through A Lens
I’ll call Nic, “Staracek” for the purpose of these specific blogs, because my name is Also Nic and I might get confused saying my own/his name every now and then.
What Staracek wanted was a camera flash (as if you were taking a photo) to accompany transitioning between menu pages (among other things). I’m no artist, and neither is he. So we can’t easily (at the moment) make a super cool visual effect, image, shader etc that easily allows us to get the effect he desired.
We fiddled with a few options that could possibly replicate or do similar to the camera flash.
We quickly tried (EMPHASIS ON QUICKLY) having a UI image and just scaling it up quickly. We though that no matter how pretty the image would be, it wouldn’t feel right. It has such an abrupt edge. Even with an image that had a softer edge still didn’t feel right. What about if there was just a solid screen overlay that was white and the transparency just faded in and out?
It felt better but it was missing a critical element to how camera flashes operate. It didn’t have an origin point, it was kind of just everywhere. I thought about how light actually affects objects and the possibility of having a light in the UI.
But there was a problem. The light even though a child of the UI Canvas – did not affect the other objects. The light was positioned in coordinates relative to the UI Canvas and it seemed like the correct place, but from what I can gather, the light in physical space and UI Canvas images interact very differently. So without spending too much time wondering how we could make that work, I jumped to the thought of light touches physical objects, why not make the menu a physical object?
Create a 3D plane object (rotate it to face the camera) and drop the image sprite onto it so it converts it into a material. At this point the camera had a Perspective projection, it still cared about depth. I created a separate Camera and switched its projection to Orthographic and untagged it as ‘Main Camera’ to avoid any possible confusion with cameras later. The Menu camera no longer cared about depth (z-axis) and only cared about objects positioned in front of it on the X and Y Axis.
Now that the main menu is a physical object on a plane and the material on it effects how the light interacts with it, I fiddled with its material properties to adjust how it looked for the camera.
Another factor that also effected what the main menu object looked like was the skybox. Because in this instance, part of the lighting came from the skybox.
Now that the menu image is a physical object that can interact with light, it needs a light that isn’t the directional light. A point light covers areas relative to its position without specif is the one I chose and gave it a ridiculous amount of range and cranked the intensity to max in attempt to cover the surface area of the image. Whilst also having it positioned so it’s origin starts where the camera flash would be.
The light alone on full intensity and a ridiculous range didn’t cover the image.
Moving the light from the exact position of the image away had the relative radius outwards flash, but after a certain point the light just started to fade away, as a point light would when it’s reach is too far from the surface. So there needed to be other layers in order for this to work. The next step was adding a ‘Sun’ flare to the point light, to really get that light crankin’.
Anything on the -y position meant in was translating backwards in world space. If it’s position on the Y was positive, it meant it was ‘behind’ the object It’s supposed to be on the z-axis because that’s forwards and backwards, but for whatever reason it’s empty game object parent had a rotation of 90 on the X. Because it’s a child of a rotation, technically Y is up towards the parent transform, but in world space it was equivalent of the Z axis, so I just ran with it. It might have not been best practice, but hey, it was an 8 day game jam – sometimes it gets messy. Anywho, as soon as it was in ‘front’ of the main menu image, the flare was really up in your face. Turns out though, the further away from the object it was, the less the flare was apparent. It was doing the reverse of the point light alone. The intensity of the light had to be decreased too, because 8 intensity with a sun flare was melting my face. 0.87f seemed like the perfect amount of intensity in combination with the flare. The light completely dissipates at very close to -100, and as the closer it gets to that number, it hits a point where the flare starts to create a flash like light right where the flash on a camera should be.
The movement that ended up being the most appropriate was from far away to then move closer. Now it’s at the stage where the light and the flare alone still aren’t covering the entire image. So in combination with the flare, I cranked back up the intensity of the point light to 8.
From -100 on the Y axis, to -20 on the Y is the most effective positioning for the light. Anything closer to 0 from -20 didn’t have any effect of the coverage of the image. What else makes stuff brighter?
In order to reach and cover the rest of the image, bloom intensity had to be 2. With everything in combination with each other, this is what created that flash effect, on a physical object in space. No matter the distance of the image to the camera. But the distance of the light relative to the object in space is what mattered. I had all the components I needed to make this camera flash, the next step was to automate it. Do all of the aforementioned in a sequence to flash up, and then flash down.
The Light had to have a -Y distance of exactly 100, the intensity of the light had to be exactly 0.87f in combination with the flare, and the bloom on the camera had a maximum of two. The solution was to
- Mathf.Lerp the transform position of the light (from -100 to -20) at a particular rate that made it imitate a camera flash (this took some iteration).
- Mathf.Lerp the intensity of the light from 0.87 to the maximum of 8 IF the lights position was -40 or closer.
- At the same time as blasting the intensity, Mathf.Lerp the intensity of the bloom on the camera from 0.1 to 2.
Then once that worked, do the exact same in reverse.
So now that the ‘Image & Flash’ for the main menu had been set up, the menu still needed a UI canvas to interact with, but this time instead of defaulting to Render mode of
Screen Space – Overlay, I only wanted this UI canvas to work with this specific camera.
After wiring up the menu, the only thing left to do was to slot the transition of what we needed to happen
between when the flash was at its maximum and right before it started to flash down.
I’m really proud of this. And this is only part one of a two part series. The next blog talks about moving Rect Transforms and automated sequences.
Until next time –