Home Artists Posts Import Register

Downloads

Content

My last post ended with this list of things to do:

  • adding a river with a funky water shader with refraction
  • ambient floating particles
  • animated low-poly animals
  • expand this out into an infinite world with non-flat terrain
  • place a player-controlled character in this world
  • player collision with the trees and rocks

I've been obsessed with this project and have completed 5 out of these 6 items. My initial goal was to learn more about lighting, but it has expanded out into much more than that.


I've spent some time analysing the lighting in Firewatch and Valheim to learn how they create such beautifully coloured worlds. The Art of Firewatch was a great watch and gave some insights into how their fog and sunrise/sunset colours work.


In this post I'll show you how I changed this flat/lifeless renderer:


Into this:


Shadows

I started by darkening the shadows more when the sun is closer to the horizon. This creates these nice sun-streaked sections of grass:


Ambience, Diffuse and Specular

The second thing I had to wrap my head around was... basic lighting concepts that I skipped over years ago.


When the sun has set, everything is black (since we have no moon). As the sun rises, each pixel's colour is increased based on three components:

  • Ambience - this is the base colour of the geometry (brown for the tree trunk, green for grass). This colour is multiplied by 0 when the sun has set, and multiplied by 0.4 when the sun has fully risen. This means 40% of a pixel's colour comes from Ambient Lighting.
  • Diffuse - this colour is controlled by the direction the pixel is facing. If it's facing directly towards the sun, it is multiplied by 0.6. If it's facing away from the sun, it's multiplied by 0. This means the other 60% of a pixel's colour comes from Diffuse Lighting
  • Specular - this colour is controlled by the reflection of the sun off a surface, and depends on where you are standing in the world. This further increases the brightness of each pixel and only applies to areas that aren't in shadow

Excuse the stock photography but it demonstrates this pretty well:

  • Ambience is the base colour (wood, wall)
  • Diffuse lighting happens regardless of where you're standing
  • Specular lighting depends on where you're standing, which is why the reflection on the floor lines up with the window



In a shader it looks like this:



Sunrise and Sunset

Originally I was trying to manage too many different colours - skybox diffuse, sun colour, horizon colour, cloud colour, fog colour - and they were all conflicting with one another.


I simplified it down two colours: sky and sun.

  • Sky colour interpolates from dark blue at night time to pale blue at day time
  • Sun colour interpolates from orange at sunset to bright cream at day time

The colour of the world is then only multiplied by the colour of the sun. The diffuse colour of the skybox no longer affects the colour of the world.


Step 1 - Add the Sun Colour to the Skybox:

The sun is a circular segment of the skybox an is positioned based on the pitch and yaw of the sun.



Step 2 - Change the Sun Colour at Sunset

As the sun sets, its colour is interpolated between bright cream and orange. The sunSpreadPower value is also reduced at sunset to make the sun section of the skybox cover a larger area.


Step 3 - Fog

The distant terrain always blends into the colour of the sky, regardless of the time of day. This means close-up terrain is black and distant terrain is dark blue.


This gives the terrain depth even when it's dark.


Trees

The current tree model is very cartoonish, so I switched to another with flat leaves instead. This also means I can animate the tree leaves as the tree sways from left to right.


Animals

Another item on my list was animals, and I found this animated low-poly Raven. I imported it into the game - having an engine makes this all a bit easier! - and rendered it in the sky.


it looks weird without animations, so I imported them too and applied them to the mesh:


What on earth is going on here?  After much painful debugging I found that the vertex weights in the raven model were imported wrong. These weights control how much each vertex is affected by each bone (e.g. the beak is affected 75% by the beak bone and 25% by the neck bone, and 0% by the tail bone).


Since the weights were imported wrong, some of vertices had a weight of 0, which meant their position was multiplied by 0 and therefore moved to the center of the model at (0, 0, 0). This is why the vertices are converging at the center of the model.


With the animations applied correctly, and the new sunset lighting, it's looking pretty good!


Playable Character

Flying around the map as a spectator doesn't feel immersive, and it's making it difficult to scale trees/grass/terrain correctly. I searched through Sketchfab and found these animated low poly people. I love the style and animation quality and think it's a great placeholder character:


The character's height is currently clamped to the terrain so there's no jumping, but you can jog and sprint around the map. I eventually switched to a physics-based controller using BepuPhysics, which I'll cover in a future post.


Water

A game can't look good without water! To start I rendered a flat blue transparent plane and applied the same pixelated noise to it.


I then struggled for a while trying to get pixelated specular lighting to work.


I thought it would be cool to have crystal clear water, but make it difficult to see into when the sun is reflecting off it. To achieve this effect I increased the opacity of the water based on its brightness.


The light cyan water combined with the orange sunlight creates this nice swampy green colour. I also stretched out the trunk of the tree (so the leaves are higher up) and changed the 2D grass to a taller reed-style texture when it's near water.


Currently the character just runs through the water like the Terminator, so I added a swimming animation (from the Sketchfab pack) and kept him afloat when he's in water.


Next Steps

I'd like to chop some trees down and build some houses, so I'll be integrating this project with BepuPhysics next and working on a building snapping system.


I'ved uploaded 32 videos and 540 screenshots to Dropbox, which show the development process from start to finish.


Next YouTube Video

I've started working on the next YouTube video about removing all loading screens from a game, so I **should** spend more time on that but I am addicted to this project.


I think I've figured a good process for creating videos. Rather than polishing it from the start, I've quickly recorded the script alongside basic animations in Inkscape and put it all together in Davinci resolve. This way I have the entire 'storyboard' laid out and can see how everything fits together.


By doing this I've already found heaps of areas to improve. Iteration is very important. I'll share the rough draft here soon to get more feedback from you all.




Comments

Anonymous

The way ambience, diffuse, and specular interact was so interesting. The way you've explained it seems really simple in concept and created a very beautiful scene! Do you have any thoughts on ways this future project will be differentiated from existing titles? There are many Building survival games out there, so if you're planning on continuing this project past just the learning aspect, I'm curious if you've thought about that at all

vercidium

No thoughts yet, just enjoying the process (a bit too much) I’ve never created tile-based building systems, or animation systems based on player actions (like swinging a sword) or combat systems with enemies. Everything I’ve built has been voxel/FPS based and there’s so much more I’d like to learn

Anonymous

Looks awesome! This is currently the kind of thing I'm trying to build aswell