Old Reading Room
I'm happy to share my last project I have been working on as a part of my bachelor's thesis ! :D It was made in Unreal Engine 4 and took about one month to get the first version of the scene. If you're interested in the process, I break down most of my texture work here !
Old reading rooom
Hello ! :)
I'm happy to present this environment I have been working on as a part of my bachelor's thesis. The goal of that project was to create a game environment using multiple texturing pipelines. The first one was the standard "sculpt/bake" pipeline, and the second a complete procedural texture creation pipeline (inside Substance Designer).
I'd already been wanting to try out new texturing techniques for a while, so this project was perfect for that. I also used this scene to work on my lighting skills, as I've always struggled with lighting in Unreal, and I'm pretty happy with the result here!
A little further down, I show part of the process behind the texturing for both versions of the scene. If you're interested, take a look, you might learn something new. :D---
The main inspiration for this environment was Stefan Dietze's "Nature Strike Back" :
First Version (sculpt/bake pipeline)
Second Version (procedural pipeline)
Process Breakdown :
The aim of this project was, as mentioned above, to test several texture creation pipelines in a simple environment in order to compare their strengths and weaknesses. Two of the pipelines I used were the following :
1) The classic sculp/bake pipeline (usinge Zbrush and Substance Painter)
2) A fully procedural pipeline (using Substance Designer)
I chose a fairly simple environment that could use as many texture types as possible in order to experiment with both pipelines in multiple relevant situations. These are the types of textures I had to produce:
o Tileable/seamless textures (man-made)
o Tileable/seamless textures (organic)
o A trim sheet
o A foliage (and decals) atlas
o Unique object textures
I began the project by laying the groundwork for the environment, scene construction, lighting and camera positions. I also specified the general shape and structure of the trim sheet and atlas texture maps, which had to be similar from one version of the scene to the next (to avoid changing most of the asset UV's).
As the texture work was the main subject of this project, I'm going to present it specifically, starting with the first version of the scene.
Pipeline A : Tileable Textures
The main challenge with these textures was to make them tileable from a fairly organic creation process. Fortunately, ZBrush offers a few ways of doing this.
Starting with a simple square plane (representing the final texture space), the Array Mesh panel lets you create four versions of the same sculpted plane, all identical to the main one. When you add a cube to the plane (with an IMM brush, for example), it will be replicated in each copy. In this way, you can ensure that each brick is aligned with the others, even if they're not on the same side of the texture.
For the brick wall texture, I sculpted 8 bricks, which I then simply duplicated to obtain the entire surface. I added a little plaster between the bricks, and made sure that each one had a different polypaint color (which I could then use in Substance Painter to create individual brick masks).
For the plaster and floor, I used exactly the same technique, plus a small parameter that you can apply to each brush, making them perfect for tileable textures.
In the Curve panel, the Wrap Mode slider defines the number of times each brushstroke will be repeated after a certain distance (vertically and horizontally). At 2, it simply allows you to work on one edge of a plane while ensuring that it blends well with the opposite edge. Just remember to activate it for each brush used to sculpt the texture.
These two simple tricks make sculpting tileable/seamless textures a breeze!
Pipeline A : Trim Sheet
The trim sheet started in 3DsMax where I set up the different pieces of the texture map using simple geometry. This base defines the final form of the trim sheet and the size of the low poly. As some sections of the trim sheet needed to be seamless, I sculpted and baked the map in three parts in order to be able to use the ArrayMesh feature (the shape needs to be in the center of the project).
Combining tileable textures into a single texture map turned out to be a bad idea, as Unreal doesn't really have a way of "cutting" a texture map and making a specific part of it tile with itself. It's certainly possible to do this, but it's perhaps a bit too complicated for nothing.
Pipeline A : Unique object textures
There's not much to say about the sculpting and texturing of the individual props. I used the standard pipeline, starting with a low poly in 3DsMax, which I then detailed in ZBrush to make the high poly from which most of the texture information was extracted. It can be useful to play a little with ZBrush's polypaint to create masks before sending meshes to Substance Painter, and to play with the AO and Curvature maps generated by the bake. By using these maps as masks, you can quickly achieve a good result without actually painting anything.
Pipeline A : Atlas
Creating a foliage atlas in ZBrush allows a degree of flexibility that can be very useful. I started most plants with a plane cut using a specific mask created in Photshop, a black outline of a sample of the plant/leaf I was trying to reproduce. Add a little thickness, a little texture work, and a little deformation, and you've got a good base for your atlas. I had a hard time making it detailed enough to appear realistic, but from a distance it doesn't really matter.
Once each plant has been created, it can be easily arranged as desired to obtain a 3D version of the atlas.
The final plants were then built in 3DsMax.
Pipeline B : Tileable Textures
Making tileable textures in procedural is rather simple : it is by default. You just need to be aware that some nodes can break the texture's seamlessness, like the Transform 2D, if you move part of the texture too much.
I won't go into detail about each node used to create the texture, but I will highlight a few combinations that I find useful. The basic brick pattern was created with a Tile Sampler (actually two, to have two rows of bricks of different sizes), which drew the main shape. By modifying the parameters, you can already define different sizes, orientations and depths for the bricks.
One combination of nodes I use quite a lot in most graphs is Slope Blur Grayscale and Perlin Noise couple. By connecting the former into the slope input of the blur, you get a nice edge deformation for whatever shape you give in the first input. Just make sure to have the maximum number of samples (32) and a relatively low intensity (between 0 and 1, I'll say). Replacing the Perlin Noise with one of the Cloud Noise allows for finer edge details. Whenever you add a new shape, you can always run it through this combination to add some basic detail and break up the overall uniformity of the outline.
The Height Blend node is also very powerful at combining multiple materials in a texture. I used it to blend the bricks and the plaster between them, as well as the two layers of the ground texture.
Pipeline B : Trim Sheet
The most difficult part of creating a trim sheet in Substance Designer is getting the scale and position of each part correct. For this project, I had divided up my original plane (the one I used to create the base for the first version of the environment) in a precise way. For example, one of the small wooden beams took up a third of the texture map in height and 1/8 in width. With this kind of measurement, I was able to reproduce a simple image in Photoshop that defined each cut. I then imported this image into Designer to guide the construction of the final texture.
I worked on each part separately and only combined them at the end. This was particularly important for the tileable parts of the trim sheet.
Pipeline B : Unique Object Textures
Starting from a low poly and adding each piece of information procedurally seemed a bad idea, not to say probably impossible. So, the texturing of each unique object was carried out using the high poly produced for the first version of the scene as a basis. But the model was only used to generate normal, ao, curvature and other useful maps. The rest of the texturing process was done procedurally.
And to be honest, it didn't really seem suited to this kind of task. It was functional and I got reasonable textures, but it took a lot longer than in Substance Painter, and I didn't have any way to paint details on the object.
Nevertheless, this part may be an opportunity to introduce a new Designer feature I can't live without anymore:
Portal nodes are the best way to clean up a graphic and make the texturing process much smoother. In short, they allow you to connect multiple nodes without seeing the wires, and that changes everything.
First, they make the graph much more usable. Imagine a mask used by the height map that you'd need for the base color; instead of having a long thread running from the mask node to the color section, simply use a portal node. You can go back and compare the brick wall graphic (when I didn't use portal nodes) and the floor graphic (when I started using them). The former is simply easier to understand.
(Below, the texture graph of the chair, without and with the use of a portal node).
Portal nodes also make Designer easier to work with. If we take the example of the mask used for height, we could connect this final mask to a portal node, rename it accordingly, and now, whenever we need to access this mask, we don't need to search for it on the graph but simply call it up with a new portal node.
And it works for everything.
Need a curvature map derived from the normal to create the base color or the roughness? Place a portal node just after the final normal map and you can call it up whenever you need it.
Need an ID card generated during baking to create multiple masks? Connect this output to a portal node, and use it wherever you need it. You can even make a portal node for each color group!
One last way that you could use portal nodes is to make packed texture maps for export. When I started this project, I didn't know if there was a way to export an ARM (AO, Roughness, Metallic) map from Designer (well, I still don't). So I created my own method!
I added a new output (named ARM) that I defined with an RGBA merge. To do this, I simply put a portal node in front of each output (Base Color, Normal, Roughness, etc.). This node is always connected to the output, so I can work as usual, but it also sends the information directly to the RGBA Merge. This way, I don't have to worry about the ARM map, which is automatically created.
Similarly, the final opacity output is collected by a portal node, to be sent to another RGBA Merge, this time to put the opacity into the alpha channel of the base color.
Once I'd found all these ways of speeding up my workflow, I created a graph template already containing most of the portal nodes, with the automatic ARM output for example.
If you want to learn how to use them, you can watch this video explaining how they work:
Personally, I don't see how anyone could work in Designer without this feature.
Pipeline B : Atlas
The foliage atlas was constructed about the same way as the first pipeline. I created the subparts of each plant, made multiple variations of each, and combined them to get the final foliage pieces.
To get the leaves' base shapes, I used a technique combining a Curve node blended with some gradients and a Histogram Scan to get a black and white mask, following the curve shape.
This video explains it quite well: https://www.youtube.com/shorts/CnMwLJ3xINs
For the veins and indentations I used a Tile sampler to make two rows of irregular horizontal lines. With a Directional Warp and appropriate gradient you can make it bend to form a "V" shape. It can then be blended with the main shape in a multitude of ways to create the leaf shapes.
I then created a custom output for each leaf and used their graphs in a separate one (as a custom node). In that new graph, I connected each output to a portal node (them again) to get to the masks easily. After that, it was just a matter of combining them to create the clusters. Most plants were built that way.
Finally, each part was combined in a big final graph where they were placed in a way to reproduce the first atlas version (from the first pipeline ; like that, I would have no need to adjust the foliage UV's).
This gives you a nice overview of my texturing process ; I'll not go over the rest of the production, as it's rather standard and not the focus of this project. I learned a lot with this environment, and it gave me a better insight of the different texture creation techniques as well as new ideas to try out for the next ones.
I hope you found the read interesting, and that you maybe learned something ! :D