The landscape now has information in the Y axis(downward), as you dig the tiles change from soil to stone to granite. It’s kept quite simple at the moment but later I want to add further noise manipulation into the algorithm so that the player can find pockets of different types of rock as they dig.
Excavation into the side of a hill
I made some progress on creating tools which the player can use to manipulate the landscape. The excavation tool allows a player to select a rectangular region to dig downward on. At the moment the excavation is done instantly but later it will be dug out by players game units.
I’ve added rudimentary support for voxel volumes.
I had wrote before about GPU picking which worked reasonably well as a temp solution. However the problem is that because the cpu is just reading the positions buffer on gpu, you can’t pick any locations that are not visible on screen. As I was using the excavation tool this became problematic and made the tool unintuitive. Not only that, on my old and useless macbook pro the PBO(pixel buffer object) was still stalling the cpu despite PBO’s being non blocking. The new solution involves casting a ray from the camera through the terrain and calculating where there is an intersection. Works a treat, don’t know why I didn’t just do this before really.
– Refactored the worldgen noise sampler.
– Refactored the precipice mesh generator
– Fixed a bug where the world tiles were actually be rendered mirrored on the Z axis.
– Fixed the camera fog distance from showing unrendered geometry when zoomed in.
– Oncreen nodes now hold a component which links to the underlying world object.
Orthographic vs Perspective
Up until now I’ve had the game camera set up as an orthographic projection. Which gives a similar style to an isometric game but in 3D. I went for this initially because I wanted it to be reminiscent of games like Age Of Empires and RCT. It wasn’t until I started working on the construction tools that I realised how it was becoming difficult to visually understand the terrain and where to place objects. It really doesnt work all that well. Because orthographic cameras have a fixed depth you essentially lose some important information regarding the position and shape of the 3D objects. It makes them slightly harder to understand and also makes it difficult to judge distances in the game world. Games like Monument Valley take advantage of this to create optical illusions and interesting puzzles. For this game though, I don’t want illusions, the most important thing is that the player can understand quickly what is happening in the game.
A slight problem with using perspective camera is that the method for grass rendering I was using did not work as well. As I was using shell rendering It only looks decent when looking downward on the world, with a perspective camera it just didn’t work. Rendering the grass that way was quite costly anyhow, so I had no problem removing it.
New Perspective Camera
I put a little time into getting a working visible day and night cycle. In free floating camera mode you can see the sun in the sky at the correct position. The sky itself now changes color according to the time of day, so for example it will turn orange near sunset. At night the distance fog is changed to give some atmosphere. At night time the focal point of the camera emits light, this makes it so you can still see the surrounding area as well as giving an eerie atmosphere.
I wrote last update about screen space ambient occlusion and how the performance hit was too large to justify the effect. I’ve been playing around with some other methods with some success. I can’t bake occlusion into the mesh because the terrain itself is actually just a displacement map. What I thought of doing however is to calculate the AO by sampling the adjacent pixels from within the displace map for each vertex. You can see the results in the day/night pictures above.
A bit of time was put into the ECS which will manage all the world objects. I put together a placeholder tree model and spawned 10,000 of them around the map. The viewing distance for the trees is not to great in floating camera mode but in normal construction mode It works fine.
Small update this time. I have started working a day job again and so haven’t spent much time on the game. For a bit of fun I’ve been thinking about implementing screen space ambient occlusion, something I haven’t written before. As I’ve been developing and experimenting with the game I’ve noticed issues with my eye being unable identify height and depth of the tiles. Often 2 tiles will sit at different heights but the same orientation, meaning they will be lit exactly the same. Take a look at this example.
The tile in middle is shaded the same as the tile behind. While it’s not difficult to understand what tile is where, It really shouldnt require any thinking. To solve this I started looking into ambient occlusion techniques, I had a form of AO in the game before using an AO value baked into the terrain verts. However, Now I have redone the terrain mesh system making that no longer an attractive option. The most common AO in games is SSAO (Screen Space Ambient Occlusion), there are different implementations but essentially you would use the positions and normals buffer to sample surrounding pixels and calculate if they occlude the current pixels.
I put together a shader which does just that. The results are decent however there is a significant performance hit. I’m using a half size AO buffer and 16 samples, then a 4×4 blur. Framerate goes from about 160 to just about keeping up at 60. I’m sure I could optimize further and improve the method, however I have played round tweaking parameter and even at high sample counts the results are not that great. I think I am going to take another look at baked AO.
SSAO After a lot of tweaking
- Added a way to recompile shaders at runtime so I can make modifications to shader code and see results instantly (Very useful, should have done this ages ago!)
- Improved pipeline for adding 3d models.
- Made headway on ECS for managing game objects.