Day to Night to Day
Decided to write something about the day to night cycle in Far From Noise, just because!
For story and structure reasons, the game is kiiind of split into 'acts'. Not really, and it won't be conveyed with any text or anything like that, but it's just to carry the story and conversation forward in an unnoticable way, and to illustrate this I'm using sunset/night/sunrise.
So the day to night cycle thing is something that's important to the story; it effects the conversation and vibe and it keeps things looking fresh.
Also they're really fun to do! It was the first thing I did because who doesn't like a good day to night cycle eh. I love that stuff in games, brings things to life so much and it's JUST COOL.
Things with Far From Noise are still mid-dev. Majorly. But here's how it looks as of now:
I'm not saying I'm doing it 'the right way', but I'm doing it some kind of way! I think the thing that makes day to night cycles work really well is just layering up a bunch of different elements and making sure each state looks good in it's own right. And I'm definitely not there yet! But I think a lot of the important steps are there.
So here's a breakdown of what I think are all the elements in the game that I change over time:
Fullscreen colour grade
Colour tint on the models
Sky gradient colours
Light rotation, intensity and shadow strength
Specular intensity on the sea
Sun animation and colour gradient
So i'll just touch on a few of the more interesting parts. I won't be delving into code really, if you want to know anything about that let me know, but this is mostly just techniques, I guess.
Day To Night
I have this main DayToNight script which controls all the timings and fires off events to mark each state change. So if the fade time is set to 10 seconds, every 10 seconds that script is like hey the section finished and other scripts in other places react; the sky will start interpolating to the next set of colours, and so on. That way I can set the starting time of day for testing and also speed through all the states to make gifs. Yay!
Here's what the DayToNight script looks like in the editor:
So all the serialised fields are just timings for things or settings I want it to control. The bloom gets adjusted, the rotation of the light sources for shadows stretching, the vignette amount, etc. And then most of the individual elements in the game will be listening out for the events and they've got their own sets of public variables.
Thinking about it I should split all the light/image effects stuff out of that script into their own separate classes too...
First here's a quick run through of the camera image effects:
(ignore the double deer... )
Just the vertex colour models (leaves are sprites) without any effects:
Everyone's favourite friend: BLOOM (and a slight vignette) - both just the standard Unity image effects:
And finally I use the glorious Amplify Color which is on the Asset Store and amaaazing. Not a massive difference here because I originally coloured everything with this palette in mind, but you'll see. It's just a really simple way to grade the whole screen with photoshop.
So those don't look that different. But by changing the blend texture, it's then really easy to blend into sunset colours or whatevs.
Jobs a good 'un. Thanks Amplify Colour!
(I am not sponsored by Amplify Colour)
Then once the sunset is finished, I'll swap the normal texture to the sunset one and set the blend texture to the night one.
Next thing is the sky. Thought about making a skydome type deal but it was just easier to make it 2D. Now my approach is probably laughable, but it works so who cares? Not me!!!
I wanted a three way gradient rather than just a two-er. I have a two way gradient shader in other places (the sun) with just a lerp between two colours based on vertex y position, EASY. But I couldn't really fathom a calculation for a threeway in a shader without thinking too hard about it, or using if statements, so I modelled this:
Then I just set the colour of each vertex in a script and lerp them. Don't judge me.
The models I usually vertex colour when I make them, then a shader sets the colours to the vertex colours, then adds some lighting using LIGHT_ATTENUATION in the fragment shader and lerping the vertex colour by the attentuation, getting some sweet shadows that are effected by directional lights (so you get shadow strength).
Then finally I tint the whole model by multiplying that final colour with another colour, so when night comes for example, all the models will be tinted with a turquoisey blue so the models don't pop out. (I forgot to do it in the example at the top with the deer so you can see how out of place he looks and how it looks when ~I don't do it~ )
The car is a bit weird because I couldn't decide what colours to model it and I'm terrible at concepting, so I split the model into sections, coloured each in just RGB and set the all the red values to some other colour, and the green and the blue, and I set them with this:
So the car goes from this (just looking at the main body):
And by changing the tint colour multiply, to this:
Pretty simple riiiiiight.
I might end up going back and recolouring it properly now I'm happy with these, which is what I did with the stag, but I find this approach works pretty well for tweaking colours in Unity.
I have a script that fades the public colour values by name so something like _TintColor in the shader will get interpolated over time. One benefit of splitting things into RGB is I can change the window tint of the car when it gets to night so it looks like lights are on inside (I know you could just split the model and have different materials, but ya know).
Here's an example of the editor view for the cliff model:
Everything else is pretty obvious - just moving the position of the sun and things like that, but one thing that was a quick experiment which turned out quite nicely was the stars.
Wasn't sure how I was gonna do it and had ideas of masking in a star texture or something like that, but what I've ended up with - and this may just be for the time being - is a particle system. Kinda simple really. It just emits little diamonds from a big thin cube that fills the sky:
And then the duration, emission time and start time are all set with a script that listens for the DayToNight events and checks the fade time. The emission rate is set to a curve so they fade in and fade out nicely.
That's pretty much all the interesting things going on. I'll talk about the sea another time...
So now you know most of my secrets!
Hope this was useful or insightful in any way.
I'm still getting the hang of making games so if you've got any suggestions of ways that I could be doing these things better or if it was helpful, let me knoowwwwwwwwwww. Via e-mail or twitter or in person or whatev!