Displacement, Scatter ( 3ds Max | C4D ), and Pattern ( 3ds Max | C4D ) can all be used to create different kinds of surfaces and distributions. Depending on the use case, one of the methods may be more convenient to use and work better than the others. Usually, the choice depends on the available assets and the intended end result.
- Displacement - deforms a surface along its normals using a texture and UVW coordinates.
- Scatter - distributes instances of 3D objects on an object. The instances are not deformed to match the surface curvature. Scatter provides additional tools such as transforms randomization, map-driven distribution, slope limitations, spline include/excludes, and more.
- Pattern - covers a surface with a pattern made of 3D geometry. The pattern geometry is deformed according to the base object's UVW coordinates and curvature.
The below table shows what components are required when working with each of the features:
Displacement | Scatter | Pattern | |
Repeated instance/node | X | ✔ | ✔ |
Base object | ✔ | ✔ | ✔ |
UVW mapping | ✔ | optional | ✔ |
Texture/mask | ✔ | optional | optional |
As you can see, Scatter has the lowest number of requirements. The main difference in the requirements for Scatter, compared to Displacement and Pattern, is the UVW mapping.
Grass Example
Let's create a large grass field using Displacement, Scatter, and Pattern, large enough to exaggerate the differences between the three methods.
The base plane is 100x100m, a small grass patch (500 polygons) is used as instanced geometry. There are 3 billion polygons in total when using Scatter:
To achieve a similar result with Pattern we first need to create a larger rectangular patch from the small patches. A rectangular patch is needed to also correctly fit the Pattern node's Crop Box. The created patch contains 200 smaller patches, 100,000 polys in total:
Here is what we can achieve with Pattern after tweaking its settings for some time to match the Scatter result:
Pattern gives reasonably good result, takes 10 times less memory, and is about 12% faster to render. The generated grass is actually denser - the crop box cuts off some of the 100,000 polygons of the larger grass patch but we are using 15x15 tiling set in Pattern, generating ≈ 80,000 x 15 x 15 = 18 billion polygons.
While pretty good for this case, remember that Pattern will have some drawbacks over Scatter: vast functionality of Scatter is missing - animation, transformation randomization, further modifications, and adding of multiple instanced objects, map-driven distribution, etc. Additionally, in close-up renders Scatter is superior in quality, as it has no random grass cuts which appear in the case of using Pattern.
For still shots from relatively far distances Pattern can be an alternative to Scatter. Though you will not get all the features of Scatter, you can still achieve the color variations if needed, by correct usage of the CoronaMultiMap.
It is also worth trying out Scatter with the larger patch. Here is how it looks like:
The naturally randomized look of a grass field is, subjectively, achieved better (Pattern result may seem too uniform, Scatter has non-uniform variations), and scatter with larger patch can look better than with the small patch.
But more importantly: even though Scatter with larger patch generates over 3x more primitives (10,000M compared to 3,000M), the parsing is almost as fast as for Pattern and again there is about ~10x less memory used, than with a small patch Scatter.
So, using a reasonably large instanced geometry is better for Scatter.
But there may be issues as well: if the scattered instances (patches) are too big - instances may appear to be out-of-bounds from the base object. The optimization here will vary from case to case.
Pattern, in this sense, can guarantee no out-of-bound geometry.
Displacement performs the worst in the case of grass. There is hardly any map which can be used to create good-looking grass strands and the required resources are not justifiable.
A close enough result with reasonable settings (same material used as for the original grass strands model):
Parsing took the longest in case of Displacement and the result is worse than in the cases of using Scatter and Pattern.
Performance summary for Grass example (AMD Ryzen 5950X):
RAM usage (GB) | Parsing time (ms) | Speed (Rays/s) | |
Displacement | 5.6 | 15,483 | ~8,080,000 |
Scatter - small patch | 6.4 | 8,863 | ~9,240,000 |
Scatter - large patch | 0.676 | 400 | ~9,300,000 |
Pattern | 0.597 | 219 | ~9,560,000 |
For grass example, Scatter with larger patch gives the best result. Even though Pattern is faster, it still looks repetitive. Scatter with its better randomization gives a more natural look to the grass. Displacement is the worst.
Chainmail Example
Let's see another example - a chainmail pattern on a deformed surface. The base plane is about 760x760cm, the chainmail patch is 3.5x3.0cm. These values were used to correctly set up the tiling.
A chainmail pattern was created using toruses and then sliced. A height map was generated from it for displacement. The texture and the model can be found here.
When using Displacement, the water level option can be used to cut off the bottom parts of the pattern. A value of 0.3 was used in this case. The quality and performance also vary depending on whether Screen space or World space displacement is enabled.
Here is the result with Screen space 1.0px displacement:
And here is the same with World size of 0.1cm:
As expected, World-space displacement (which is mostly intended for animations) takes much longer to parse compared to the Screen-space one. It generates significantly much more primitives and takes over 11 times more RAM.
In both cases, there are slight artifacts in the chainmail units, more noticeable with World size displacement - they are not perfectly cut-off at the bottom because of how displacement works.
Pattern gives the best result here, parses the scene almost 3 times faster, renders cleaner image in the same time, and there are no artifacts, as the actual geometry is used:
The same thing done as accurately as possible with Scatter (using the UV distribution method and the same geometry as for Pattern) looks like this:
Scatter takes about the same time as screen space displacement for parsing, but is over 70% faster in rendering (Rays/s), leading to more passes rendered. The scatter instances are not deformed based on the underlying surface though, so they look "blocky" in the render.
Performance summary for Chainmail example (AMD Ryzen 5950X):
RAM usage(GB) | Parsing time(ms) | Speed(Rays/s) | |
Displacement - scr. space | 0.788 | 419 | ~10,300,000 |
Displacement - wld. space | 9.2 | 6,392 | ~10,600,000 |
Scatter | 0.691 | 549 | ~16,700,000 |
Pattern | 0.55 | 207 | ~10,000,000 |
The takeaway: Pattern is the clear winner in the case of a repeated geometry.
Conclusion:
- Use Displacement when specific maps, including one for displacement, are available for the final material or surface you are creating.
- Use Scatter when you want the most functionality and randomization - instances of multiple objects, animations, spline include/excludes, map-controlled distribution and randomization for scale, rotation and translation, etc.
-
Use Pattern if you have the pattern geometry ready or if it can be quickly created, and if the UVW coordinates of the base surface are correct, to project the 3D pattern as expected. Pattern is intended for repeating patterns (think of roof tiles, perforated metal floor, etc). If you need something more organic and randomized, for example with random scale, rotation, positions, where the instances are overlapping with each other - only Scatter can do it.
Note also that Corona Pattern does not produce actual geometry, it cannot be converted into, for example, editable poly. It is created only during render time.