The final chapter in the morphing and LOD technology testing, for an open world on current hardware.
The goal of the last few months have been to build new or use existing technology to allow for a huge open world type of game, that will typically run on high end current hardware.
One of the first goals were to ensure an outdoor environment, like the clouds and the sun, can move in a realistic sort of way, including shading the clouds depending on the time of day, creating an in Game map and compass (*zoomable), and world map of arbitrary objectives, creating an inventory system, to view inventory items, using an offscreen camera and render texture, that proved to be pretty simple.
Another starting goal was to enable equipment like clothing and armor to be equipped and retargeted to another character’s skeleton *(with the same biped bone structure).
The last few goals were to test and ensure multiple characters *(including all their clothes/armor/facial animation) can be created, from a single base character, using morph targets.
And imported and used in Unity, in an efficient manner, all of these goals, have been reached.
Another goal was to ensure scene geometry, can be used on a large scale in a large envronment, using LOD. This was tested on mutliple occasions, the first was using a sphere containing almost 35K polys on LOD0, and dropping hundreds of them in the scene randomly, and keep dropping them for fun, and making characters attack and destroy them using a particle magic system.
Goals also included all of the above with post processing effects, like HDR, realistic realtime Shadows and lighting *(NOT lightmaps, yuk), Lens Flare, Bloom, Depth of Field and Scatter, Camera Motion Blur.
The final test was ensuring we have proper tools for workflow between Max and Unity, when it comes to creating characters, their morph targets *(including customization and facial animation) and their equipment and hair, eyes etc..
And tools to create meshes in Max, and export them for LOD import to Unity, using Unity’s built in LODGroup, and their naming convention, which also proved extremely useful.
The artwork seen so far for these goals, will certainly be done better, but that was never the goal for creating new code and tech, as it would slow down the process too much, and it should, because it must look great too. Although I strongly suspect the character models will be used, and probably a few new ones, or monsters… who knows…
This post will detail creating the rocks and trees, and the tools created/used in the process for creating the final scene for morphing and LOD tests, in a huge open world, every bit of scenery/geometry visible, *(except for the clouds), are traversable terrain, where any character can walk to.
The first step was to create the hi poly rock in Max, as I don’t like the idea of having vertex lit rocks, and bumped specular rocks….*(get it?.. whatever)
Following the Max tutorial from Autodesks website to create a rock was pretty straight forward, but I will still detail it here too.
All my Max Units are set to cm, I create a sphere, with 25cm radius, ensuring to pivot and place at the origin.
The next step is to add a noise modifier, ensure fractal is ticked in the noise rollout, and then for every rock I created *(3 base rocks in total), I changed the X,Y,Z strength values, to between -30 and 30, the mesh is then scaled uniformly on Z, to about 70 or 80%.
Always reset XForm, re-pivot and center to origin after scaling/rotating/translating to avoid possible matrix issues later on.
The sphere originally had 32 segments, which will give it about 960 polygons, which is way to much for a rock, don’t need that much detail, so I add multires, and halve the vertex count, 400 is fine, some of the trees in my final scene, have over 3K… *( but they billboard on LOD to 2 )
The next step is to UV map, because of scaling, the UV’s will be distorted, and I don’t like the default spherical UV’s anyway, rocks are nice, as their textures do not have to tile at all, as it looks better when the same texture is rotated, scaled and painted over the same section in Mudbox, adds more realism to the final result, and normal and displacement maps, also look good.
I then export to Mudbox, and paint on a rock texture using a projection brush, the textures I used here, are courtesy of www.gameinstitute.com ‘s texture and 3ds Max modeling course, which I completed in 2012.
I make sure to check the scale of the texture, so it will match more or less the size of my rock, and I also rotate and scale the texture slightly, and repaint over itself, to add more detail, this process takes but a few seconds in MudBox.
With this process completed, I export the paint layer *(1K PNG)
I then use another tool, CrazyBump to create normal and displacement maps.
For my rocks in Unity, I want parallax specular, I don’t mind if it looks a little funny, but it actually looks great from a few meters away in Unity, and adds awesome realism, to do this, I export the normal map as 32bit TARGA, and add an Alpha channel in Photoshop, then copy the displacement map, into that channel. Unity will use the Alpha channel of my normal map, for providing the height for the parallax shader.
I then import the maps into Max, just to view the diffuse and normal map on the mesh, and look for any weird seaming or texture artefacts.
The final process in Max, is relatively straight forward, I want my rocks to have 3 levels of detail, on each level, I want 30% of the total level of polys, Unity can automatically create an LODGroup component, when you prefab an FBX, that contains meshes, that end with the name _LOD0…N, where [meshname]_LOD0 is the highest LOD.
I wrote a script that will simply add a multires, snapshot each level at n-30% of vertices, and then simply select them all and export them to FBX, using whatever FBX settings were last used, which is almost always exactly what I want. *(unless it isn’t and I have to go back and do it again), luckily, this process *(of exporting) takes all but 1 second…
I then open and check the exported FBX, in Motionbuilder *(coz it quicker to move stuff around in, and check the vert counts) , just to see if it worked.
3 meshes, with varying level of detail and correct Unity LOD naming convention done.
The next step is to import into Unity, pretty straight forward, no need to import rig or animation, and keep all the optimization/normal/tangent settings, as rocks won’t deform with morph targets in this game 😉 .
Also, I need to create 3 materials, LOD0 will be parallax specular, LOD1 will be bumped specular, and LOD2 will be specular, they need to be friggin specular, otherwise it looks not good, even from far away.
Another important step is to prefab each rock imported, this will then also, automatically create the LODGroup component on the game object/prefab, and you can play around with any settings if need be, but really, the defaults work pretty good so far.
Also while I am checking each of the LOD meshes in Unity, I drag and drop my corresponding LOD material on, luckily Unity made the LODGroup contain a GameObject, so you can drop whatever you need in there, for that LOD, typically, I would keep the scripts etc.. on the parent game object, but for materials, this is how it works, and it works well.
On LOD0, my hi poly mesh will be visible, shaded with parallax specular, from LOD1, my LOD1 mesh, with bumped specular, and LOD2, only specular.. And LOD2 is visible from pretty far away, so far away boulders and rocks in the distance, still don’t look too bad.
I also add a Box collider, and NavMesh obstacle, to the parent game object, because my characters, will need to traverse, and navigate around these things.. as best they can using Unity’s NavMesh. Although I had to interfere and write a simple script to determine if the character is stuck, so he can go somewhere else, just like the Magic Combat test game, this will be a factor in the real world for sure.
The next step was to get some rocks in there, the quickest way I could test this, was to write a simple random scatter script, to resize, rotate and position the rocks randomly in the world, around the origin, as my terrain is centred about the origin. Also note, in these examples, I am still using Unity’s built in trees, BigTree and Palm tree, just like the previous samples, but shortly, I would have to create my own, and test that process too.
In total, I added 3 base rocks, and dropped 300 of each in there, that is 900 rocks, although I brought it down in the end for the final scene, because my characters had no area to traverse, there were just too many rocks/boulders for them to find a decent path.
Then I dropped in a few characters, the same ones from the previous tests, with full customization and equipment morphing, including a simple test animation, driven by Mecanim’s animator.
The last step for this process is pretty uneventful, as Unity’s tree creator tool makes this process extremely pleasant, I created 5 different trees, using Unity’s tree creator, you randomize branches, their growth, very similar to what I learned to do at game institute, they also teach you to write a procedural tree generator, which also looks really good, but we did not do LOD/Billboard, which is friggin awesome, once your tree is created, Unity maintains a separate folder for each tree, and keeps it’s textures and a sprite / billboard texture of it, which it will automatically switch to, and orient to the camera, if too far away, making creating forrests, a breeze.
For the textures, I used textures already provded from Unity’s tree package, but to create tree bark and branch/leaf textures isn’t all that hard from digital photos. But the bark and branch textures, do have to tile though.
To ensure grass and vegetation would also look good on a large scale, I used Unity’s grass and grass2 textures, and painted in the entire area with thick short patches of grass, the grass will also sway in the wind.
And then I used the terrain -> mass place trees function, after adding all my trees to the terrain editor, and I placed about 500 or 600 trees, too many, and once again, my characters have nowhere to go, as they keep on colliding with trees. Performance wise, when in the unity editor, things can start to slow down, but when running/testing the game, everything runs better than smooth.
Here are some more screen shots, of the final scene, after dropping in about 15 characters, and keeping my 150*3 rocks.
FPS was very good, way above 140 most of the time, with close to 1M vertices to work with in total *(if everything would be rendered, and no LOD)
Also, I re-used my rotating skybox from an earlier goal, and created a new skybox in Bryce, although not visible here, the top of the skybox, is actually still not aligned, and need to be rotated.