Ishan Verma shared an enormous and in-depth breakdown of a new material inspired by Piccolomini Library and made in Substance Designer and Unreal Engine 5.
My name is Ishan Verma and I work as a 3D Material Artist at Ubisoft. In this article, I will explain how to authorize fully parametric high-quality floor tile textures using Substance Designer as well as the breakdown of blend material and showcasing it in Unreal Engine 5.
It will be a comprehensive walkthrough where I will cover points like Reference search, Reference breakdown, Creation strategies, Height building, Material creation, and Rendering in Unreal Engine 5.
The main idea following this study was to explore non-destructible parametric workflows and to create something new out of them. So, I started exploring reference images and came across a place called Piccolomini Library and the floor there caught my eye as it was way expressive, so I decided to recreate it in Substance Designer!
Any project starts with following up on a mood board or a collection of references. Without such a mood board sometimes an artist gets off from what is meant to be achieved. Below are some points mentioned which an individual can concern and follow up while starting any texture creation project.
Things to do:
Things to avoid:
Reference breakdown contains a diverse image collection of features that are planned to be implemented in the material. Reference breakdown is usually important to mark out particular parameters an individual wants to put in specific places. Here I’m giving a brief example of how I broke down the reference for myself.
In this section, I will be talking about some ideal points to keep in mind before you start working on the textures.
So once done with the reference collection and breakdown, at the beginning I will create a template then start experimenting and building the Height Map.
Here is an example of a template for material creation:
The first step for the Height building is to create diamond-shaped tiles, which will be the base of the material. For that, I started the flow with a Uniform Color node with white color, then used a transform 2D to rotate at 45 degrees and a levels node to tighten up the shape which will avoid mipmap issues. Then I used two 2D transforms to squeeze the shape diagonally and horizontally to make it into an actual diamond shape.
For aligning the diamond shape, I used two Splatter Circular nodes with a shape count of 6 for both diagonal and horizontal shapes to create circular patterns. Then I blended both the circular splatters using a blend node with add blend and plugged one level node to tighten up the shape.
Then I plugged the shape into a tile generator and tiled it as X=4, Y=4 and increased the shape size till the gap gets occupied by the corresponding tile and changed blend mode to max lighten.
Then I used a Flood fill & Flood fill to a random grayscale node to vanish out the gap between the tiles and used one edge detect node which will give a thin crevice from the random grayscale data. Then I used one bevel node to give a very trifling bevel depth to the pattern.
For the border shape, I followed the same steps as above but here I divided the flows into three shapes. The first one is an inner diamond and the other two are outline borders which will consist of a chain pattern in between.
Now for chain pattern creation, first I wanted to create a chain base. For that, I took a shape node with Circle as the main shape plugged it into a 2D transform to make it small, and then using a blend mode subtract it from the main circle.
Then again, I took one Uniform Color node as white, transformed and mirrored it, and blended it with the ring shape we created earlier. After that, I used another 2D transform node to make a small version of the arc. Now using 2D transform, rotated it 180 degrees and blended over. For concluding the shape I just used a slight blur and levels to make it actually a unique shape!
Once chain base shape creation is done, plug it into a tile generator with X=1, Y=14, this is how we will achieve chain shape. Then use a 2D transform node to make it slant according to the diamond shape we created earlier and two mirror nodes to make it fully into a diamond silhouette.
For creating the crescent pattern, I simply used one shape node with a circle shape and subtracted a smaller circle out of it using a 2D transform and blend node. Then I used a non-uniform blur grayscale node to give a slight depth to the crescent and plugged the shape into two splatter circular nodes and added both of them.
Once done with the final shape then plugged it in the main tile generator with the same parameters as the diamond tile generator so the shape equally fits on top of the main tiles.
For surface treatment, I kept it simple. Started with a slope blur node with the main height and a blend of Clouds 1 & 2 as noise input. Then inverted it using an invert grayscale node and used a histogram scan with exposed float parameter. This parameter will help us to move from 0 to 1 value mask so we can create edge chipping procedurally. Once done with creating the chipping for the blend mask, I just took one histogram selected from Flood Fill to a random grayscale node and blended it with the chipping histogram scan. Then blended it on top of the main shape with subtraction mode!
For adding more surface formations, I used one Flood Fill to Gradient node, with this node I created random gradients on each tile shape and blended it over top of the main Height with SoftLight Blend mode. Once done with this, I created another mask from Flood Fill to random grayscale and created the same blend as what we did for Chipping pass. Here we will create the same parameters which will help us to create random surface unevenness.
For adding surface warps, I took various noises like Clouds 1,2, Gaussian Noise, and BnW spots 2 and drove all of them with a Directional Warp with Flood Fill to random grayscale as intensity input. This method will help us to create warped noises which can later be blended over the main shape with multiple blends.
For generating large cracks, I started with a Shape node and splattered it using one Splatter node with random size, rotation, and grayscale values. Then used a Distance node to maximize the distance between those splattered shapes. After that using one edge detect, it will give us a base crack shape. Then used a warp node with Gaussian noise as input to give those cracks some organic feel.
To get a small crack pass, I followed up with the same steps shown above but put the octave or I say shape tiling more to get smaller cracks consistent. After that, for masking, I used histogram select and blended it with cracks then subtracted it from the main shape.
Once cracks are subtracted from the main shape, now to give more depth formations I did a Bevel node to the particular crack masks we created earlier and levelled them up to tighten the shapes. This will give a debris pass to use along with cracks.
Now to give more surface and edge details to debris pass, I did a slope blur using a blend of clouds 1 and 2, this will deform the edges and give it uneven height. After this step, blend the debris slope blur pass on main cracks using histogram select mask.
For creating grime pass, I started with Clouds 2 node, increased its tiling with Safe Transform Grayscale node. Then took Clouds 1, BnW spots 3 & Gaussian Noise and blended them one by one using SoftBlend mode with 0.5 intensity each. Once done with grime creation, I blended it with the main height output using the Height Blend node.
For the tile removal pass, I just used one Histogram Select node, took input from Flood Fill to grayscale node, and exposed all three parameters to expand features of the graph. The first parameter here is for Position, which will help to tweak the position of missing tiles. The second one will be Range, this will increase the area or amount of area for removing tiles and at least we have Contrast, which will help to tweak the unnecessary masking.
Height and Normal:
For Roughness I started with a curvature smooth from the Normal node and blended it with the BnW spots-2 node. Then I took one tile generator masking the inner diamond shape and blended it twice with grunge 14. As well for each parametric iteration I created several slider masks and blended as Subtraction mode for each mask. So it will give an independent slider for all-over Roughness with the occurring damage.
As the parameters for material are changed, the same will be effected to the roughness.
For Ambient Occlusion, I started with an AO node and used a histogram select to mask out damage then blend it over the main AO. Then I wanted depth where the tile will be removed, so I created one mask for tile removal and blended it over the main blend, and plugged it in AO output.
It has the same blend setup as Roughness with particular masks from each tile sampler.
Due to fewer color values used in the material, I kept the color inputs way less. Started the process by creating mask blends from all tile samplers and blended them with an Add Blend mode. Then used the Levels node to level out any noise from the mask. Then for adding more realisticity to the mask, I warped it a bit with Grunge Map 014 and blended the main Height again on top with SoftLight mode. This mask will be used for the Blue Color pattern.
For the Base Color pass, I started creating a pale white color using an edge detect from main height to a Gradient Map and tweaked the color using the HSL node. Then I took another gradient and plugged the blue mask we created earlier as input, as well as driving it to form a blue color output. Then blended it on top of the white base color we created before. By this process, we create the primary color blend pass for the material.
For the parametric blends, I started with creating masks from each feature I exposed earlier in the material for example cracks, damage, edge chipping or edge damage, etc using histogram scan/select node. Then used all masks within specified blends one by one so it can work with the main height parameter tweak.
As we already know Unreal Engine 5 is publicly available and came with game-changing features such as Nanite and Lumen it gave a huge leap in terms of technology. So I decided to test it out for my material project.
In this portion, I will talk about how to set up a scene for a render template, 4-way blend shader, lighting, and few more additional features. The whole step-by-step process is mentioned below.
Our first approach for this part will be creating a render template that includes importing an asset, setting environment settings, and lighting setup. Later on, we will move to the rendering and post-process.
Firstly, I created one sphere and base mesh for the scene in 3ds Max. Then imported it in engine with import settings below:
Now for setting up the post process, I started with exposure values by setting up metering mode to manual and exposure compensation to 10. After that setting blooms to standard mode with intensity at 1.4.
Then I turned on Lumen in the Global Illumination menu and did the same for reflections. If you have performance issues, then below the method there’s an option called Final Gather quality, this can be turned on and tweaked using values for decreasing the precise intensity of Lumen.
And finally, in the post-process volume setting, an option called Infinite Extent can be ticked to unbound the volume box limits to the whole level.
For setting a camera, I started with placing one camera actor in front of the template scene. Then I switched the projection mode from orthographic to perspective. Field of view at 30 degrees and aspect ratio as 1.045 to make it square frame as well tick the constraint of the aspect ratio option.
For creating a 4-way blend shader, I started with importing textures in a stacked manner with proper nomenclature.
A Splat Map is a texture that controls the blending of multiple textures (or other values) across a model.
First I created a basic material, then imported all textures into the material editor. After importing I organized all of them by type into particular frame boxes with proper namings. For the first blend, I started with dragging one Vertex Color node and created a blend of 4 textures with the help of the Lerp node like in the image shown below.
I followed the same method for blending ARM, Normal, and Base Color Maps. For ARM, I divided the blends into pairs. The first blend here is for AO, took the R channels of each ARM map then multiplied it Base Color to give fake AO depth.
After that, I created a blend from G channels to create a Roughness Lerp blend with vertex data and plugged it into the Roughness channel.
Vertex data here will help to weight paint the mesh with 4 textures modes.
Now for the parallax bump offset, I started creating a tiling setup with a UVcoord node multiplied with an exposed float 1. This tiling will be plugged into the coordinate input of the bump offset node.
After that, I created another Float 1 and exposed it as a parameter, named it as Height Ratio, and set the value as 0.012. Then I plugged this float into the Height Ratio input.
Then for the height offset, I took the height splat map and plugged the height from each RGBA channel into the height input. Once done with the BumpOffset setup, I plugged it into the UV input of all textures.
For mesh vertex painting, selecting the Vertex Paint option will open the paint box. From there I selected few parameters which can be found in the image below:
Once done with vertex painting, I plugged the material into the render sphere. Below you can see the final render output from the camera viewport.
For taking high-quality renders in Unreal Engine, from the viewport options dropdown menu there’s an option called High-Resolution Screenshot. It will open up a pop-up. From there we can set up a size multiplier by 1 to 4, we can go with maximum numbers depending on the high-end systems.
Throughout the process from material creation to practical use, I brainstormed a lot and yes the results were worth it. I wanted to expand my skills in terms of creating a fully parametric material in a productive manner, so I decided to give in a taste of unreal 5 to the process. I highly recommend each individual to stay on track and find ways to learn things in-depth as well as welcome all your mistakes as serendipitous because you never know if silly mistakes can give you a good workflow by chance in Substance Designer. Try to catch up with different workflows and keep experimenting unless it’s worth proceeding. Be observant and develop a good visual library, It will really help to improvise your detailed workflow.
Believe it and keep greatness coming!
Feel free to contact me on my ArtStation or Instagram. Thank you 80 Level!