This will provide some detail the high level workflow I used to create a huge open world, with 8x8KM densely populated with vegetation, trees, grass and mountains using Unreal Engine 4 World Composition, along with several other tools which I will go through briefly.
NOTE: Unreal Engine 4.9 version only.
The idea is to use World Machine to create a huge open world, and then export them as tiles, which are then imported as levels into UE4, using UE4 World Composition.
I added a Terrace and Erosion output device, and connected output nodes to them to save out RAW height output for the terrain, and added Slope Selectors to output weightmaps that will be used in UE4, to assign materials to the landscape, based on slope angles.
Here is a view of the endless entire planet that world machine generates, the square hi-lighted here is 8x8KM of terrain. Which is what will be exported as 2KM tiles, giving 16 tiles in total.
This is the section that will be exported.
Here are some of the options used to export.
Here you set en ensure your world extents (8KM), and under the tiled build options, each tile size, for future use, I would make the tile size smaller as such large tiles stutter when loading in a packaged game, populated with meshes. The maximum elevation is used in a small calculation when importing into UE4, as described in the tutorial, and I did not click the “Flip Y Axis” option, as UE4 Tiled Import already supports flipping Y, with an option.
When setting the options on the Height Output node, ensure the “Participate when building tiled worlds” is ticked, and output format is set to RAW16.
When setting the options for the slope nodes, I chose 0-18 degrees for Grass, 18 – 46 degrees for Sand and 46 – 90 degrees for Rock. These weights will then be exported as weight maps, and imported into Unreal Engine, where you can specify useful names to assign materials to your landscape, based on this slope angle.
When you click on Build Tiled World in World Machine, your raw Height and Weight maps will be exported.
The landscape textures were created using Photoshop, from digital images from CGTextures.
I also darkened them as I found when they rendered they were too white washed. But I later found a better way of introducing a material parameter to control the lighten on any given texture in game.
Rocks and Mountains.
The rocks were created with full LOD in Max.
Including scatter rocks as well as mountains, the mountains were scaled up in UE4, and the UV tiling was done in Max.
All have LOD.
All vegetation was done in SpeedTree for UE4 Subscription.
Models include Wind/Vertex animation, Ambient Occlusion and LOD up until BillBoards with normal maps for the lowest level of detail, the trees and grass were modeled using the same principals in SpeedTree. Most textures came from pictures from my garden, so they can look a lot better, and some came from CGTextures.
When compiled from SpeedTree, the textures export along with the asset, which are then imported into UE4.
These vegetation assets, including the Rocks and Mountains, were created for a previous project, which I re-used here.
I had to darken the textures again, but that won’t be required for the next project as the custom material node I created can handle lightening a texture with a parameter now.
The character skeletal mesh was created in Maya.
The mesh was simply created using simple face extrades, then Auto UV mapped, and bound to a single bone, as a skeletal mesh is required for UE4.
The character textures were created in Substance Painter.
I created 2 materials, one for the ‘Eye’ and one for the body.
These were then exported as PBR textures (Base Color, Metallic, Roughness, Normal) to be imported into Substance Designer.
The textures were imported into Substance Designer, and then hooked up to the right nodes, and published as an sbsar file, that contains both his eye and body material in one file, when imported into Unreal however, this is then split into 2 separate materials.
Character Mesh Import and Setup.
The character mesh was then imported into Unreal Engine4, as a skeletal mesh, and the sbsar file from Siubstance Designer imported, then the materials applied to the character.
This is a screenshot of the imported Substance Designer material, for his Body.
This is a screen shot of a scene from UE4.
The persistent level in UE4 keeps everything that you want persistent across all levels of your game. I included a level blueprint here, so that the player can change the graphics settings, simply by pressing 1,2 or 3 for Low, Med and high Graphics. This is also where your Player Start, skysphere etc.. resides, then place your level start in the location of your world tile, where you want it to spawn. If you place your PlayerStart in a tile/level, in stead of the persistent level, you will get a black screen when you play your game, with a warning in the log file. NO PLAYER START.
Upon such a keypress, the blueprint will simply invoke console commands to set various graphics settings, as laid out in the UE4 Scalability Settings.
After importing the tiles and weight maps exported from World Machine, the Levels were present, but they are not loaded into memory by default. Here I loaded a tile and zoomed out.
Here I loaded 3 tiles, and zoomed out, and am also showing the World Composition window, which you can open by clicking “Summon World Composition” from the Levels window.
After importing tiled levels, the landscape will have no materials assigned, you have to create it manually using the technique described in the tutorial.
When I imported the weight maps, I assigned the names: Grass, Sand and Rock to the Low, Medium and High angled weight maps, as they were imported. So in the landscape material I can reference and sample for grass, sand and rock, to use and place various components like grass meshes, vegetation, mountain meshes on the rock layer.
This is done by adding Landscape layer Weight nodes in the material editor in UE4, and assigning the corresponding landscape textures to them, along with a Landscape Coords node, to tile the UV input for the texture samples and normal maps. I chose to use 25 as the Landscape Coords Mapping Scale value, giving a nice close up value, as most of the terrain will be covered in vegetation and mountains, this worked pretty well.
The material also includes a Grass Output Node, which contains 2 Grass Types, one for green grass, and one for dead or brown grass.
Grass Mesh and Grass Type Actors.
The grass mesh was imported from SpeedTree with it’s LOD.
I also imported the Textures from SpeedTree, and used one of the imported meshes as a base or parent for all my 2 sided vegetation or leaf material.
The parent material was originally created by importing a SpeedTree mesh, and then I modified it, to include a Lighten parameter, to lighten or darken the texture, at any given time.
The parent material also includes a normal map for higher level of detail materials.
For the lower levels of detail meshes, excluding the billboard, I created another material instance, of which the parent material only supplies the Texture Sample, and not the Normal map as well.
For the Billboard material, I created another material instance.
The parent of the Billboard material uses a normal map, as I found normal maps look much better for billboards which are really far away.
Setting up the Grass Type actor, for use on the material landscape.
These grass type actors, will be used in the landscape material, and connected to the Grass Output node, of the Landscape material, so that when the landscape is rendered, the grass will also be rendered. You can specify many options here, I chose to use 10,000 Unreal Units for my culling distance.
I then imported the various bush, tree and rock SpeedTree assets.
All meshes include a similar setup with regards to materials, they all use an instance of a material for higher, and lower level LOD, as well as for billboards, all which support a Lighten material parameter, that I set based on how dark or light I want the texture to be when rendered.
All vegetation, excluding grass but including rocks and mountains, contain collision data, and you can not run or fly through them, you can walk on or over them, so I would suggest using a custom UCX for collision when exporting, as UE4 collision algorithm does not generate very close collision data, so you will end up floating well above the meshes and mountains when you walk on or over them, for crashing into them, which is what this demo is all about, it works 100%.
The next step was to create Procedural Foliage Type actors, for each or the different types of Bushes, Trees, Rocks and Mountains.
The setup varies slightly between the different types of vegetation, as you want to play with seed density, scale, slope angle, and for the Bushes, I also told it to only spawn on the grass and sand layers. I also had to change the collision radius and shade radius to get the exact amount and spread I wanted for all of the assets.
Mountain Procedural Foliage Types.
The mountains were scaled up by a huge amount upon import.
I then created a Procedural Foliage Type for each of the different types of Mountains, and ensured to set their slope angle to only spawn at high slopes, so as not to spawn on grass, or where you should be able to walk. The collision radius and shade radius was also set very high, as I did not want them to be too close together.
Grass Type Shader
After creating the various grass type actors, and connecting them to the correct nodes I added in the Grass Output node, of the Landscape material, the grass renders where ever it samples the landscape material of that type, like ‘grass’ or ‘sand’.
I also added a Wind Directional source, to each tile, so the grass sway in the wind, using the vertex animation exported from SpeedTree, but only for LOD levels high enough, lower level LOD and billboards do not sway, and that is simply done by removing the SpeedTree node, from the material you set on the lower level LOD.
World Composition and Procedural Foliage Spawning.
After creating Procedural Foilage Type Actors in the content browser, you create a Procedural Foilage Spawner, and assign your types to the spawner, that you want to spawn. You simply drag and drop your spawner into the tile you want to spawn, not in the persistent level, that won’t work, it has to be in the tile or level you want it to spawn stuff on. Then it is positioned and scaled up so that you cover the entire area you want to spawn in, in my case, all my tiles contain FPS spawners, they are all the same spawners from the content browser, but I had to drag and drop them into each tile, position and scale them to what I wanted.
The large sphere visible here in the Left view, is the skysphere, and that is in the persistent level, the little rectangles are my FPS spawners, here are 3 tiles visible, and each having their own FPS spawner.
I created 2 Procedural Foilage Spawners, one for the Bushes, Trees and Rocks, and one for the Mountains. The mountains do not need to worry about colliding with vegetation, and my vegetation spawner already contains 19 or more actors that it spawns, so it does have some limits, but it worked better separating them, as it also gives you more control over where what spawns.
All of the procedural foliage actors, have their own culling setup, through their procedural foliage actors. UE4 also introduced screen door fade or smooth LOD transitions, which works really well. Mountains and trees are visible for about 75,000 unreal units, whereas bushes are only visible for 35, 000. The grass type actors cull grass from 10,000 unreal units.
Speedtree models sway in the wind, but only the first 2 high level LOD.
I created a custom C++ character class for the Orb.
The character always moved forward, but when it detects a collision, it will start moving upwards, and if it does not detect any collision for a while, it starts moving slowly, and downwards. It also raises BluePrint events, as it decides to randomly adjust it’s speed, and turn and start going in another direction, and when it thinks it is stuck.
The class was then extended in BluePrint, the Orb skeletal mesh added, some Environment dust, a glow sphere component that surrounds him, which will change color using a dynamic material instance as and when he detects things, and is notified by C++ to do things. He also has a second sphere collision component, that is only used for overlap events, so that he can be notified when he is close to something beneath him.
The glow sphere material was created by creating a material instance, from a modified version of the ocean water, that ships with starter content for UE4.
The material exposes a few parameters, but the only one I am changing is the “Water Crest Color” which is the glowing/shimmering coloured light, that surrounds him.
The material was simply altered, I removed all nodes I did not need, changed it to be translucent, supplied a static opacity value, and added a rotator node, to rotate the mask, that is used as an alpha value, for a linear interpolation node.
Character Construction and Event Graph.
In the construction part of the BluePrint, I created a blueprint variable, and store a reference to a created dynamic material instance, created from the glow sphere material.
I also created a BluePrint function to reset the color of the glow sphere.
The event graph was responsible for :
- emitting sparks, and oriented correctly from the hit point, when colliding with something.
- changing the color of the glow sphere, red for colliding, green for busy turning, yellow for stuck, reset after 5 seconds, blue for normal.
- playing sounds for the various collision and movement or rotation sounds, and applying the correct pitch, based on the character movement speed.
- if the stuck event is raised from C++, an explosion will spawn, an explosion sound will play, and the character will shoot off into a random direction at an accelerated speed.
The C++ code will also randomly call the stuck method, so that the character can move off to far away locations quickly, but it will only do so, if the second collision sphere, at the bottom of the character, is currently overlapped with anything, thus preventing him from shooting off into the sunset, or out of the skysphere.
Here are some more in game screen shots.
Some of the screen shots were also taken with Low, and Medium graphics setting, by pressing 1,2 or 3 in game.