Pseudo Random Asset-Damage based on Vertex Color and Object Position
Maya, Tool, Python, UnrealEngine4, Material
Here is a short video demonstrating the Maya script and usage of the materials in UE4. The complete workflow is explained below.
The initial goal for the script, material and workflow was to increase the variety of environment props that are placed frequently and maybe close to each other, without increasing the workload required by a large amount.
I focused on the damage of assets as it is something that can look odd if the same props with the same damaged areas are placed next to each other. The case that interested me the most was damage that is not only visible in the texture but also requires a different mesh topology.
The script and material should integrate nicely into existing workflows and be easy to use for artists. To demonstrate how it works, I chose the workflow for a realistic asset for a third or first person persective game.
Another critical feature was the independence of tessellation. This would allow the effect to be apparent when tessellation is disabled or not possible on the target device.
I started by making a low-poly block-out and sculpted a clean version using it as a base. After that, I did a damaged version based on the clean one. The damaged version has the maximum amount of damage that is going to be possible to show on this asset. It is important to note that the damage can not overlap in the current version of the script and implementation in UE4. I am continuing to research methods to allow overlapping damage and combinations of different damage maps.
The clean sculpt was then retopologized and UV mapped. To retopo the damaged version I added edges to the clean retopo. These edges hold the extra detail for the damaged version. By deforming the mesh the damage can be represented in silhouette as well as in the texture. This could, depending on the assets, be much more optimized. I choose to leave it unoptimized, to be able to see the topology of the clean version a little bit better.
It is possible to use the same maps for the damaged and clean versions. However, as I already had a damaged high-poly I baked the normalmap for both versions seperately.
After the retopology was done, I moved to Substance Painter to create the mask required by the material to randomly pick a damaged area. It is important to note that the masked areas should not have a smooth falloff. An additional mask with falloff can be used for blending between clean and damaged versions. This would be the case if a smooth transition is required for the material to look correct.
The material works best when using stepped colors in the selection mask. Therefore, damage-areas that should be visible at the same time have to use the same value. Otherwise every damage-area should use a different value. In this case I used 10 different areas so each area has a 0.1 step in value. While it is possible to ignore stepping in the mask and UE4 material, I do not recommend it as it might produce unpredictable results.
4. Maya Script
I created this script mainly to learn how to build Python scripts for Maya. I quickly found myself using the Maya Python API 2.0 as the assignment of vertex colors is much faster than regular Maya commands and the handling of meshes is more convenient. The UI was built using QtDesigner and the resulting .ui file was integrated using PySide.
The script calculates a world-space 3D heightmap based on the difference between the clean and damaged version. The topology of the clean and damaged meshes has to be the same, just like it has to be when creating blend shapes. It is possible to select whether Y or Z is the up-axis depending on the target engine. In this case I chose Z as I intended to use it in UE4. The heightmap then gets normalized and bias-scaled to fit into the 0 to 1 range vertex colors are able to cover. This process comes with a loss of precision. Fortunately, this is barely noticable unless the mesh has extremely large displacements in positive and negative space. After clicking on the “Calculate Morph Values” button you can see the final result in maya and a prompt appears displaying the scale to use in the UE4 material. The alpha is set to 0.5 by default and is used to manually adjust the visibility of the damaged areas in the engine. A field to adjust the alpha may be added to the interface in the future.
5. Unreal Material
In UE4 the mesh containing the calculated values is used in combination with a simple material setup. In order to easily use the calculated values in any existing material I created a few material functions that are not only usefull for this single task but can also be used for other things.
The “MF_PRandomDamage” material function uses both “MF_ColorMaskCheap” and “MF_RandomFromPosition”. This is the default function to use to blend between the clean and damaged version of an asset in a pseudo random manner. “MF_ColorMaskCheap” outputs a clipped mask based on the input texture and color. “MF_RandomFromPosition” outputs a random color based on a position and a noise texture. By default the position used is the object’s position. It is possible to clip the output to a specified number of steps.
The material used for the result shown in the video looks like this:
The material function not only selects a random damage area to show but also can influence the overall amount of damage that is visible. Both, the overall damage amount and influence of the random damage amount can be adjusted manually. Additionally, it is possible to add and remove damaged areas by painting alpha values of 1 or 0 per asset respectively.
Here you see the same asset stacked and duplicated multiple times, all using the same material with the pseudo-random color shown. The following gif shows different values for “DamageAmount” and “RandomDamageAmount”. To increase the visual effect of the randomness the user could rotate the assets in addition to the random damage.
This project has enabled me to learn very much about scripting in Maya and has sharpened my modelling pipeline skills.
Although the intended usecase for the script and material is position-based damage of the same repeating asset, the different parts may be used for other applications. The position-based pseudo-random generator’s output could be used to introduce color variation for vegetation or other props.
Despite achieving the desired result I have identified a few limitations. The largest of these is the lack of overlapping damaged areas. This could be realized by baking the calculated vertex color into one or more textures. However, this would increase the overall texture memory quite heavily and would not be very efficient in terms of iteration speed. The use of vertex color for pseudo-random damage also limits its use for other things like texture blending.
Areas where this work has further potential could include aging environments or interactive art-directed destruction. Both applications would need modified versions of the material functions and possibly some adjustments to the script but they would follow the same basic principles.
Songs I frequently listened to during this project:
- The entire Mirror’s Edge Catalyst Soundtrack (AWESOME GAME) by Solar Fields
- “Club Foot”, “L.S.F.” and “Underdog” all by Kasabian