The use of procedural generators in creating content for real-time 3D applications: Part 2. Valley Benchmark
Valley Benchmark
This is the second and final part of an article on procedural methods for producing content for 3D applications. The first part you can find here .
In this part, as well as in the previous one, there are links to downloading the source materials we created, which can be freely used (with or without changes) in our projects, but only not to sell / distribute in pure form and / or as part of or libraries. ')
We remind that all these source files were not subjected to any special preparation, processing or optimization in order not to embellish the real situation (quite often in the process of work one has to sacrifice the versatility / convenience of the created solutions in favor of saved time).
This time we will talk about what tools and techniques we used to create the Valley benchmark in order to produce a large amount of photo-realistic content in the shortest possible time. You can evaluate what we have done here by downloading the benchmark for free or simply by viewing the video:
So, while working on this project, we were faced with the task of creating the most realistic Siberian mountain valley with dimensions of 8 x 8 kilometers with a large variation in the scale of the objects created (from mountain to flower in the meadow) and a high level of detail.
Before proceeding directly to production, we smashed all the necessary content according to the principles of the approach to its creation:
meshes and textures of stones, trees, grass, flowers, etc.
landscape (and masks of various objects spreading over it)
textures for specific effects, some natural phenomena and objects
If the content specified in the first paragraph is created in most cases by any familiar means of 3D modeling and texturing, then the items listed in paragraphs 2 and 3 require special approaches, in which procedural generation tools were used.
For example, the World Machine program was used as a specialized tool for generating landscapes and object distribution masks, and the Filter Forge program was used to create:
In the Unigine engine there are tools for simulating both physically correct dynamically changing clouds (physically-based volumetric clouds) and creating static clouds of the desired shape in the required places (billboard clouds).
The tool for creating billboard clouds allows you to form an array of billboards (billboard is a polygon that is always sent to the camera) randomly, filling them with the initial bounding mesh according to specified parameters (for example, such as number, base size, size variation) , and further manipulate all the parameters until the position of any individual billboard is changed.
Setting the parameters of the Billboards object in the Unigine engine
To turn the resulting array of polygons into clouds, a special material is assigned to it, taking into account the light from a global light source (the sun), as well as light scattering. This material assigns a diffuse texture consisting of several separate semi-transparent cloud fragments, which are randomly assigned to each individual billboard.
The diffuse texture of the cloud fragments was created by the procedural tools of the Filter Forge editor.
Mesh, in the volume of which cloud billboards are generated (above) and diffuse cloud texture (below)
To create moss on stones in Unigine, a special material is used, which allows you to combine 2 materials, one of which is projected onto the second mask in world space.
Moss Material Parameters
The convenience of this material is difficult to overestimate, because if you just bake the moss in the texture of the stones, we immediately lose the opportunity to freely rotate (on all three axes) and position these stones on the landscape (I want the moss to lie only on top of the stones), and also lose the necessary the randomness of a simulated natural object, which will immediately be noticeable and, in general, will have a bad effect on the realism of the resulting image.
The shape of the moss fragments is determined by two textures - a coarse but unique for the entire surface of the landscape mask and a detailed, but repetitive (due to tiling) alpha channel of the diffuse texture. These two initial transparency values ββare multiplied together, and the result is a detailed, unique moss pattern at each point on the surface.
All textures (including the normal map) and the mask for this natural object were generated in Filter Forge.
Diffuse (top), normal (middle), irregularity (bottom) moss textures
With this material, it is also easy to simulate rust, corrosion or mold on objects.
Lens Flares Dirt
Effect of Lens Flares Dirt in action
In the Unigine engine there is an effect simulating the illumination of the lens of a camera lens with bright light sources. Since in reality there are no perfectly clean and even lenses, and the presence of even tiny motes on them causes quite characteristic visual artifacts during illumination, for more realism we added the ability to use the lens pollution texture, which appears only on its very exposed areas.
The necessary texture for this effect was easier and more convenient to implement with Filter Forge, which was done.
Creating large outdoor scenes is quite challenging, both in terms of rendering the landscape and the many objects on it in real time, and in terms of creating content for such scenes. Unigine for these purposes, there are many tools that allow you to:
create suitable for real-time rendering landscapes of arbitrarily large sizes (in addition to the toolkit, asynchronous data loading implemented in the engine)
procedurally distribute arrays of objects in the landscape by masks
form clouds, stars, rain, ocean, adjust atmospheric scattering, etc.
Before creating content for large open spaces, it is recommended to collect as many reference materials as possible with photographs of the terrain that you want to implement. Useful as ground shots, and aerial photography. Analyzing the collected reference materials, it is necessary to understand the processes involved in the formation of the earth's surface - working in procedural landscape generators requires an understanding of such things in order to achieve the best result.
The landscape in the Unigine engine is an object that dynamically changes the level of detail of its mesh and textures, depending on the degree of remoteness of the camera for optimal performance with a large visual range (more than 40 kilometers).
Landscape object with dynamically changing detail
To create a landscape in the Unigine engine, you must have the following source textures:
height map (height map) - 16-bit grayscale texture, which describes the relief (height of each point of the landscape)
diffuse map - the texture that defines the base color
material mask β a texture that defines areas of detail for a particular material (see below)
A normal map is not required, because it is created by the engine tools automatically on the height map.
For detailing the landscape, additional materials are used, the textures of which are tiled across its entire surface, and the degree of blending of these materials is given by the mask. In this way, the desired character of the surface is transmitted in the right places, be it grass, sand, stones or any other type of surface.
To create the above source textures, there are specialized landscape generator programs. One such program is World Machine.
World machine
This program, like any other, is not without flaws, but was chosen by us among others (see the list at the end of the article) for a number of reasons, including the quality of the result, the node architecture and the rich set of functions we need. Separately, it is worth noting the ability to selectively calculate small areas of landscape textures (to save computation time), due to which it becomes possible to quickly iterate when working through the details, which is always a huge plus, thanks to which the quality of the generated content will noticeably increase.
The process of creating landscape textures is divided into three stages:
For each stage, a graph is created in World Machine, and each next stage uses the results of calculations of the previous one. Of course, World Machine is quite a smart program and when changing node parameters, unlike Filter Forge, it recalculates only the branch of the graph that is affected by these changes, but when you reopen the file, this miscalculation is carried out completely from the very beginning. And since, for example, the calculation of the results of erosion is rather complicated, then by splitting into different stages, in addition to the convenience of work, we also get saved time.
Creating basic landscape textures
The graph in the World Machine, which forms all the basic textures of the landscape
At the very basis of the graph that forms the landscape, there are three noise generators with different scales, the results of calculations of which are combined to form, respectively, large, medium and small elements of the base surface:
Closer to the depressions, the hilly character of the surface prevails, which is recreated by the expansion of the areas around the mountains with a filter (and in the World Machine terminology, a device) Expander:
Next to the resulting hills are added small detailed rocks - the remnants of the mountains after erosion:
Terrace devices add ledges, then noisy to eliminate the regularity of the effect and limit their height and angle to the surface:
Erosion is added. This is the most significant device in the World Machine, which is designed to simulate the processes of destruction and displacement of soil under the influence of water, wind and temperature. Without it, the entire landscape would remain just a distant set of mixed procedural noises.
Wave undulations are added. Under the influence of gravity and erosion processes, the ground tends to slide from inclined surfaces to lowlands, but due to the large number of tree and plant roots in it, this sliding occurs in whole arrays, which visually manifests through folds on the surface of the earth. To form and work out this effect in more detail in World Machine helps the ability to calculate the results of only a specified part of the landscape (through the installation of the necessary Extents):
Snow is added to the tops of the mountains. This is mainly done by the Snow device, which allows you to simulate the effect of snow accumulation, taking into account such parameters as intensity, quantity, wind direction, etc.
The results obtained at this stage are rasterized by means of World Machine and saved to files. The result is a height map, an erosion map, and a snow cover thickness map.
Masks that determine the visibility of the materials of these surfaces on the landscape are also created in World Machine from the textures obtained at the previous stage.
The graph in the World Machine, which forms all the necessary masks
The snow mask is formed in such a way that the intensity of the original snow cover thickness map determines the size and number of pieces of snow (the darker the pixel of the original texture - the smaller the number and size of the pieces).
Stone mask
Mask spreading stones on the landscape surface
An erosion map shows how streams of soil eroded flow down. To obtain a mask of stones, places with a large slope of the landscape are removed from it (as a rule, stones do not linger on such surfaces) and areas with a slight slope are removed at low heights (small sedimentary rocks, soil and soil dominate in these places).
Grass mask
Mask spreading grass on the surface of the landscape
For this mask, heights are excluded from which the snow cover already begins.
In nature, grass grows on the soil, which in turn does not linger on rocky and steep surfaces - respectively, places with a large slope are excluded from the height map.
From the map of erosion, information is obtained about the places of sediment slipping. At certain heights, where this rock is more active (rolling down and sliding boulders), the grass grows less active. All this is also taken into account when forming a grass spread mask.
Mask of the rocks
The mask of the rocky surface on the landscape
The map of rocks turns out an exception of all other masks.
Creating object distribution masks
Tree masks
Mask distribution of fir trees on the surface of the landscape
Tree masks are created from grass masks, height maps and several procedurally generated noises so that spruce trees are located at high altitudes (but where the grass is still growing), pines - at medium heights, and birches - in hollows and plains.
All tree masks are mutually exclusive, so that there is a clear separation of forest zones. Small intersections are found only in adjacent areas.
As a result, we obtain masks by which 4 types of trees can be arranged: spruce (spruce), dead spruce (spruce dead), pine (pine), birch (birch).
Masks of flowers
Masks distribution of daisies (top) and fireweed (bottom) over the landscape
Masks of camomiles (camomile) and fireweed (blooming sally) are obtained by simply adding procedural noise to a grass mask.
Scrub masks
Mask distribution of shrubs on the landscape
A bush mask is also created from a grass mask, but with the help of an erosion mask, it takes into account the places where more water most likely accumulates, and cuts off the zone on which the stones are located.
Stones
For the location of stones, cobblestones and boulders will be used already existing mask of stones.
Creating a diffuse landscape texture
The graph in the World Machine, which forms the diffuse texture of the landscape
The color texture is created by combining the masks obtained in the previous steps. Various colors are mixed, noises are added.
For example, two types of grass are added - green and dry. Green grass prevails in the lowlands, dry - on the tops of the hills. In order to make the landscape visually darker under the forest, a mask of trees is superimposed on it.
If necessary, the necessary color adjustments are made in Photoshop or GIMP.
The resulting diffuse texture of the landscape
Placement of objects by masks
Configuring MeshClutter object settings
After all the necessary textures and masks have been received, the landscape has been generated, all the necessary materials have been set up, all that remains is to distribute all the prepared objects (trees, stones, grass, flowers and bushes).
It is difficult to even imagine how much time the arrangement of such a huge number of small (in comparison with the landscape) objects would take manually. Therefore, to save time and optimize rendering, a special object MeshClutter was created in the Unigine engine, which makes it possible to distribute objects on the landscape in a pseudo-random manner according to the original mask and, for example, parameters such as density, random scatter angles of objects, their scale, resulting from allows you to achieve the desired effect of heterogeneity.
Especially it is worth paying attention to the fact that the distribution of objects in this case is pseudo-random - that is, with the same parameter values ββ(and the same seed value) for two different generators, the objects they create will always be located in the same places. Thus, the determination of the result is also achieved.
findings
World machine
Virtues
Caching the results of calculations. At changes of the graph there is no recalculation of nodes which these changes did not affect. It is very convenient and saves a lot of time creating new content.
The presence of output nodes, which allows you to display in the files any number of readable textures from anywhere in the graph and resave them at the touch of a button.
The possibility of tile miscalculation of large textures (tiled build). In this case, the textures are rendered in fragments, making it possible to parallelize the rendering (multi-core is involved) and make optimal use of the occupied memory. However, one should not forget that the erosion algorithm in this case is calculated by simulation separately for each tile, and not for the entire surface of the landscape, and pasting the resulting erosion texture tiles is carried out by overlapping their adjacent areas.
A sufficient set of devices (basic blocks that create an algorithm for which the landscape is formed), for the implementation of virtually any landscape construction algorithms.
There is a possibility of grouping parts of the graph to create new devices for the purpose of their further reuse, but, unfortunately, there is no instancing - the devices inserted in this way will be copies.
The ability to accurately calculate only a given fragment of the landscape. It greatly saves time when working on the detail of selected areas.
disadvantages
A huge number of problems when working with large amounts of source data (both vector and raster) and landscapes of large sizes. For example, when opening a vector with coastline data (several thousand points), the FPS in the editor tends to zero.
The behavior of the erosion algorithm (Erosion Device block) depends on the final terrain resolution.
Lack of tools for the creation of mountain rivers. Cutting the landscape on the splines under the river without applying erosion gives an unrealistic result. If, however, erosion is applied, in some places the river may fall asleep across.
The inability to change or disable the interpolation of the original textures.
Some minor, but very unpleasant defects of the editor. For example, such as the impossibility of setting digital color values ββin a Colorizer device (this can only be done visually), using int instead of float for some parameters, and incomprehensible restrictions in the ranges of parameter values.
The main idea for the development of all procedural generators should ideally be erasing the line between 2D and 3D, because 2D is only a special case of 3D.
At the moment there is no procedural generator that would allow:
create algorithms for the formation of three-dimensional objects (voxels)
create your own texture baking algorithms and easily customize them
That is, it is not possible to use any information from a low-poly, high-poly or algorithmically formed voxel 3D model in a procedural generator to create, for example, a generator of seamless stone textures or textures of rust streaks for any original model.
In programs such as 3DS MAX or Substance Designer, it is possible to bake some cards from models, but all of them are rendered using algorithms that are hard-wired to the program, which cannot be changed, and there is no possibility to create new ones. Hope is given by the recently begun implementation of AngelSript in 3D-Coat, but it is not yet clear what the author wants to bring.
There is also a problem for a long time that could be solved at the current level of development of procedural texture generators: these editors have learned well how to remove seams along the edges of a formed texture rectangle (for example, using offset or splat methods), but so far none of them know how to remove these are seams on the texture where the UV coordinates of the model break.
If all these missing capabilities were implemented, they could be used to create libraries with automatic texture generators (for example, metal surfaces with weather, dust and mud factors), source data for which only a three-dimensional model would be material.