Hi there! While kinnas and the art team are busy concepting and modelling away, I’m on day/night cycle and weather duty. The main challenge here is to squeeze as much visual variation out of as little pre-rendered pixels (and final game size) as we can. We wouldn’t want to be rendering separate background images for day and night, snow and rain, etc.
The above is also the reason we are not going purely 2D but instead using very basic 3D geometry as a canvas. This gives us some extras like partially real time shadows (see below) and visual feedback when placing in-engine assets like characters.
Interior vs exterior lighting
Kinnas has only mentioned interior rendering because lighting interiors and exteriors is a very different task and warrant different optimizations and even separate shaders to make them efficient.
The main difference between the two being the behaviour of natural light. Exteriors have pretty much uniform light direction at each point in time, with light and shadows changing direction throughout the day. In contrast, interiors have light shine in from the windows (that is, each room having its own light direction which stays constant throughout the day) and daytime modulates only the light’s intensity and warmth based on the window’s direction. The latter is achieved by kinnas’s mentioned lightflow map and screencaps above.
Since interiors have quite diffuse shadows always pointing away from the windows, we can get away with a single shadow map for the whole day cycle. Exteriors, however, are not so forgiving. You have the sun forming radically different shadows as it travels across the sky. To make those shadows happen, we would need to import enough geometry to make them detailed enough and it still wouldn’t look as good as a pre-rendered raytraced shadow.
So we are not going to do that.
We are going to bake shadows for morning, noon and night and use time manipulation and weather trickery to make them work so the player won’t notice. Here’s an excerpt from a map with the three shadows for evening, noon and morning.
These channels are to be multiplied to the background albedo map each at a certain time of day. Lack of a color means that spot is in shadow and the brightness of red, green and blue means the area is lit at the corresponding time of day at that intensity.
Here’s the result switching between the shadow maps with light and shadow color grading going on as well:
I might still play around with some ideas to keep it pretty but pack the shadow information down to something less than full-size RGB map.
Also note that shadow casting between the characters and the background is real time (based on our super simple world geometry) which still needs work and is another can of worms to be discussed in another post.
Some of the switching between the pre-baked shadow states can be handled by summoning clouds for an overcast weather but that would look suspicious three times a day. We’ll need some classic card trick misdirection while the player is busy and shuffling between interiors and exteriors.
A quick weather generator
Switching shadows and daytime isn’t enough though, a world needs weather to be believable. Since these two things go hand-in-hand, I’m also doing the rain dance.
Generated by adding up some sine functions to make random but plausible looking weather data
This is what the graph says:
- X axis is for days (full numbers being midnight, n+0.5 midday)
- Y axis is for temperature/probability.
- blue: air temperature
- red: dew point temperature
- orange: precipitation (red minus blue)
- green: fog probability
The weather generator itself is going to use the above data and follow very simple rules:
- If precipitation is above 0 and temperature is above 0, it rains.
- If precipitation is above 1.5 and temperature is above 2, there’s lightning.
- If precipitation is above 0 and temperature is below 0, it snows.
- If precipitation is above -0.5, green dictates amount of fog.
- Precipitation levels between -1 and 1 give us varying amounts of cloudiness from clear to overcast to gloomy. (should have called it humidity)
With some tinkering, these functions and rules result in mostly dry weather with some foggy mornings, now and again some rain and the occasional snowfall and the very rare lightning.
Now that we have meteorological data generated, let’s have it modulate our lighting and weather effects.
Raining makes things wet
I misuse a shadow map to mask whatever comes down from sky. Looking from straight above anything in “shadow” remains dry and rest of the scene gets affected by rain, snow, hail, etc. As it comes out, this a very fun map. I can rotate the caster to simulate wind. I can add the wet areas to background’s spec map to really make it wet. I can use edge detection to map splashes under the eaves and edges of objects. With some work, I can even wet the background spot by spot instead of doing it uniformly. Finally I can use the sun’s shadow map to dry it off at different rates. Sounds like pet project material, I’ll keep you updated which of that I can squeeze in. I should probably get back to the big tasks like day/night cycles and the actual weather machine.
Here’s some normals debugging for a piece of UI.