I don’t know why, but it’s hard to focus and make progress on my current project. It seems when I play around a bit with making the level, I end up moving backwards… this week, I did some testing regarding Unity3D’s “Terrain” system and looked again at my tree models.
I had long considered myself a good expert on Unity3D’s game engine and its features. Indeed, I picked it up quickly, and there isn’t that much to it. However, there are certain features within the engine that I never bothered to study: its new (as of 5 years ago) “Mecanim” animation system never seemed necessary to learn (since its’ legacy animation system worked perfectly well for me), I never did bother with the audio tools, etc. Never mind the fact that I haven’t upgraded to Unity3D’s new 2017 version behind its new subscriber system (at the rate I’m going, it’d quickly be cheaper to pay for a perpetual license rather than monthly). One of the commonly known features is the “Terrain” editor, within the menu where you would add 3D game shapes (spheres, cubes, etc.) to your scene. I’ve been playing around with it, and tried replacing my game’s environment with it, as seen above.
Previously, I had been using a grid of separate 3D meshes I built in Blender3D to make up the ground. I figured it was a good idea to prepare a mindset where I would quickly use external tools. I thought at the time that separating the world into cells would give me flexibility later, for example to disable or hide chunks of the map that are too far away. But there are some drawbacks to this approach. Namely, my workflow was flawed from the start, since the cells would have to be precisely modeled to line up to each other without cracks, something I did not bother to do from the start (or better, I should have cut from a larger shape AFTER modeling the map). Also, I was hand-painting (digitally, in Photoshop) the textures to lay on the ground, one texture per cell, meaning well over 100 high-resolution textures. And they had to be high-resolution, even as simple as the art was, since one cell would make up most of the screen at any time during gameplay. I figured this was not ideal for runtime to have that many textures in memory. Most of the cells also had a high polygon count to allow for hills and valleys, and STILL looked unnatural for not having enough triangles (or perhaps my lack of knowledge in Blender had me using the wrong tools to mold rivers and hills).
So, I played with the built-in “Terrain” editor. It’s a fun tool that first-time users like to play around with, since you can make valleys and mountains within seconds within the game engine. Indeed, I found it easy to use my previous models as a template to ‘trace’ my terrain over, carefully using height-brushes and ‘fixed-height’ brushes to model the landscape. And now, on a whim I can edit the world as I like. The slopes are more natural, and the lakes and rivers are MUCH more natural. There is also a texture-painting tool, where you can define a texture as a brush, and paint along the terrain like a blank canvas. I can add a mountain in seconds, and I can color it in seconds too? Cool!
But the terrain engine has some weird ticks, which (like most of the built-in 3D objects in Unity) cause most developers to use other solutions. One is that the terrain can’t really scale or rotate like other 3D objects… there are size and resolution settings in the inspector, but they don’t seem to do much. That resolution is noticeable when I start painting textures… even at the smallest brush size, I can’t really add any details (forget adding ink outlines to anything), and transitions between textures can look blocky on the map. The best solution I found is that I could just use a huge brush and paint those high-res cell textures onto the terrain to get some detail… but that kind-of ruins the point.
Anyway, the main reason I did all of this. I assumed my previous modeling of the ground was inefficient, and that the built-in terrain system would be more optimized by the engine. So I did a test between the two, and this is what the profiler showed.
To explain, the game does run better outside the editor, and this does not necessarily represent the game’s final performance. And this is caught while rotating the camera around, so the huge dip at the end is when most of the world is no longer in view. Anyway, the result was… little to no difference in CPU or Memory for using a cell-grid vs “Terrain” system. Huh. This isn’t exactly scientific, but I was still disappointed.
Really, I should have done this over a year ago, but all the same, which system will I use? I’m not sure now. For it’s speed in my workflow, I will probably keep using the “Terrain” system, and decide if to switch right before the game is finished. I don’t really have time to dwell on this. If nothing else, I think playing with this allowed me to see I can fill in the world a bit more to be more dense (more hills and mountains and canyons), like most other games would be. This would hide far objects better, which might be better for optimization later on.
Oh, the “Terrain” system also allows for trees, grass and shrubbery. I was aware that the number of trees (and how they are currently using LOD) was part of my optimization woes, so I was hoping the Terrain system could better handle this. Unfortunately, the requirements to import a tree externally for the system is complex and unwieldy, it is better to use the built-in tree modeller… which looks fugly. I probably should have spent more time on this, but I admit I’m giving up on it and moving on. As for grass, that is easier to implement, and it can move in the wind too! The problem is that dense grass is difficult, and the shader automatically changes color on the grass against your will. Unfortunately, neither are usable to me.
I also did some more testing on tree optimization. Yes, trees again. I was making a new tree model for some more variety in the game. I wondered if combining the meshes (the trunk and leaves) made sense to do for optimization… everyone keeps saying to do it, but I didn’t bother because it was handier for me to be able to modify them separately. But I did a quick test to see what would happen if I did.
To explain, each model is a simple tree, less than 100 vertices, made up of 4 polygons. I was testing combining those 4 polygons to combining them as 1 polygon. I had 500 trees for each type, and enabled/disabled them during runtime to see if there was a difference. In framerate, no, because of vsync preventing the game from going over 60fps (I didn’t bother to disable this). But the profiler clearly shows how much of this was going into vsync, and how much was being used by the CPU.
Basically, in my test case, having 500 trees of 1 complex polygon was using 1.97ms CPU per frame. Having 500 trees of 4 polygons was using 6.83ms CPU per frame. This is not an average, I was peeking at a specific high frame as an example. But that shows a big improvement: I could get away with using less than 30% the original CPU. Although there was no movement, I was also pleased to have that many trees perform so well, I do wonder how much of my current game is being throttled by my animation system… Additionally, the rendering window showed “dynamic batched draw calls” and “shadow casters” was almost 4x as high for 4 polygons than for 1 polygon, which I guess seems obvious. So, the improvement is worth it, at least for objects that cast shadows?
I found all of this interesting, but I really do need to get back on track. I’ll start making a checklist, and start pushing myself more often to spend time on the game. And maybe work on something other than the environment.