I was doing a game jam over the weekend. I wanted to make fog roll in as the player got close to an object.
The natural thing to do was to stick a volume on the object that cranks up the fog.
However, this wasn’t quite right: the fog came in if the camera got close to the object. That would be fine for a first-person game, but this one was third-person!
My solution wound up being to call VolumeManager.instance.Update
, which takes a Transform to sample the Volume from:
VolumeManager.instance.Update(GameManager.Instance.player.transform, LayerMask.GetMask("Default"));
var fog = VolumeManager.instance.stack.GetComponent<FogEffectComponent>();
if (fog != null)
{
fogMaterial.SetFloat("_Fog_Start", fog.fogStart.value);
fogMaterial.SetFloat("_Fog_End", fog.fogEnd.value);
}
I use the result to set values on the fog material, which is used in a full screen pass.
I also needed to do this with bloom. Since that’s a built-in effect, I couldn’t just set values on some “bloom material”. My solution to that wound up being to create a global volume that applies bloom, and then to control its weight:
var playerBloom = VolumeManager.instance.stack.GetComponent<PlayerBloomEffectComponent>();
globalBloomVolume.weight = playerBloom.intensity.value;
This requires an extra global volume, and it’s just…kind of fiddly.
So, my question: is there an easier way to control where volumes get sampled from? It would be particularly nice if I could this only for some volumes, or only for some volume components.