Regarding The Decal Workflow Within Unreal, and a Potential Enhancement to This Process

HI All,

I’ve seen a lot of discussion about the Decal Workflow popularized by games like Star Citizen and Alien Isolation. This method for creating environment assets uses weighted normal data in its modeling is appealing for its ability to iterate quickly and get strong results while using far less texture space than if one were to bake out everything. It is also nice to be able to “float” decals and place minor accent shapes wherever you want.

There has been a problem however in that this process doesn’t give you as much freedom as one would like. In Unreal there are limitations in how decals can be used, namely the inability to blend materials from your decal sheets. There have been many requests for Unreal to expand its decal capabilities. People have gone as far as to generate custom engine builds for workarounds to this end. Furthermore, this process tends to give you a very sharp, clean look in which limits the cases this workflow is good for. I’ve seen a lot of Sci Fi corridors and such that are beautiful… but could use some grunge.

Below is an example of a method of asset creation which allows for the same freedoms of the Decal Workflow, but with all of the sweet sweet material blending. Also notice how the floating details have seamless edge wear and dirt collection. This is done using two UV channels rather than decals. There is a simple decal on this box, but all of the other knick-knacks are placed using a primary UV channel, while the rest of the material is placed in the secondary UV channel.

This method works with Unreal (also Blender, Max, Maya) right out of the box and is very efficient for both iteration time and overall memory consumption. If anyone is unfamiliar and would like to know more about this, please let me know and I’d be happy to answer questions.

Hi there! I’ve been looking into the decal technique because the project I’m working on requires large vehicle assets that could benefit from a technique that still allows for lots of fine detail without having to resort to many enormous textures.

I was able to mostly wrap my head around the “decal workflow” because I’m also familiar with Blender’s Decal Machine add on.

Can you help me understand your approach? How does your proposed technique work? What are the steps and does it also offer the benefit of allowing for a great amount of detail up-close on large assets?

Correct me if I’m wrong but are you unwrapping the main mesh into the secondary UVs and the decal meshes into the primary UVs? Or does this technique not use any decal meshes to begin with?

It would be really helpful to see a breakdown of the different maps for the details and the main mesh as well as how to set up the material.

Thanks for your time!

I kind of dont understand your workflow. I support what @ChrisCorr asked, could you show us a breakdown on everything. Its sounds very interesting and looks very good. :slight_smile:

I’d like to point out 3 things to consider with this approach:

  1. Normals on UV channels other than UV0 might get you in trouble if you flip, mirror and rotate them. That’s because the tangent base is calculated from UV0 and if your normals on UV1+ don’t match the direction of UV0, you might see inverted normals on the “decal” part of the mesh. This thread goes into the details, especially the posts by Ryan Brucks. The quote below illustrates the main problem.
  1. Performance: If you want to use POM on the detail parts (which I absolutely recommend) and you do all of this in just one material, you’re adding around 200(?) instructions to the pixel shader on the whole object just for the few parts that actually make use of it. Using a separate decal material for the detail geometry insures that your main material stays simple and performant while only a very small amount of pixels on the screen would suffer the performance drop caused by Parallax Occlusion Mapping.
  2. Regarding the nicely detailed, but rather sterile Sci-Fi corridors: I know exactly what you mean, but I think they look like that only because the artists decided to make them look like that. It’s not an inherent limitation of the technique itself. The way I see it, it is no problem to bake the grunge into the decal material.

YMMV, of course, since I don’t know your exact workflow. But I’m always interested to see how others approached this problem.

Hey @and-rad , thanks for pitching in.

I’ve read your other posts on Polycount as well about this stuff. It’s really cool that you modified the engine but for someone less technical than myself that would really not be viable, especially with updates and other stuff breaking over time.

Checking out this cool asset by Forest Telford This is exactly the effect that I’d like to achieve and it seems like nothing extraordinary was necessary (I might be totally wrong of course). At least nothing like modifying the engine so I’m a bit unsure about the limitations he ran into and how they are present visually.

I could live with limitations like not having POM and lack of metalness changes in the decals because the decals would never really be observed very close from multiple angles or for long periods of time (it’s not a FPS).

Still trying to wrap my head about all this!

@ChrisCorr Regarding the asset on ArtStation, as far as I can see, this is totally achievable with an unmodified engine version, but It might bloat the amount of draw calls (you can see that on this asset alone there are 3 material slots used only for the trim sheets). If you can accept that, then the “Star Citizen” method of texturing large meshes is completely doable without modifying the engine.

OP’s method, and I’m speculating here, is pretty much what you wrote above. You unwrap your decals on a different UV channel, matching the decal sheet you have prepared. Instead of using different material slots for these details, you blend inside your main material pretty much like standard layer blending is done, or you blend per material attribute using Lerp and If nodes.

Take grunge for example: Your decal texture might contain channels for metalness, roughness and grunge. Plug a Lerp node into the Base Color pin, plug the grunge channel into the Alpha of the Lerp, and connect the grunge color and the object’s base color to the node. That’s the basic idea.

I’ve also come across this video:

With this it seems that metallic is working with Dbuffer decals as well as a way to have POM using UE4 decal domain and blend modes, which if I understood correctly from the other threads about this issues, wasn’t supposed to be working in UE4? I feel like I’m missing/not getting something.

The documentation also specifically states the DBuffer blending modes are non-metallic, yet the pin in the shader isn’t greyed out when switching to those blending modes.

Still hoping for some details from @JamesCLight :smiley:

Don’t worry, the only thing that you might be missing is up-to-date information. POM has been available in decals for years and metalness in DBuffer decals has been implemented by Epic in 4.20 or 4.21, I think. So any discussion about this that’s from 2018 or earlier is bound to have some outdated info.

Hi All,

Sorry for the late reply, I posted this a couple of weeks ago and thought it was lost at sea. I’m glad there are responses and questions! As @and-rad stated the details must remain on the first UV channel because of the tangent base. I’m also using an iterative bump-offset (3 iterations) in this setup rather than POM because it ischeaper.

I wasn’t aware that DBuffer decals had gotten a hike in 4.20, but I still think that this workflow I’m describing has some advantages. Namely that the decals, the trims, and the tiling texture which holds the grunge are all contained within the same material and placed seamlessly with the edge damages and grime following your details. The below example is three objects referencing the same material, the only thing different is the UV0 channel and some cuts on the object to the right. There is also no opacity being referenced, which can be expensive all on its own.

To answer @ChrisCorr, Doing things this way is almost texel-density agnostic. You could build a tank with it or a gun and the trims/floaters would not look too big or small. The reason why is that the grunge is an entirely separate entity from the details. The edge wear and dirt are not baked in, rather a short set of shader instructions meant to mimic what you get with something like smart masks in Substance Designer. Those tend to use Cavity and AO which are threshold-blended with grunge so they are an important part of this setup. So I’m using Normal Map, ID Map, and Mask (AO, Cavity, Height). Even though there are a few shader instructions in total, it stays in the green.

In the bunker project I did recently, almost everything was made with one trim sheet and one grunge map (four image textures).

To elaborate on the specifics, the separate maps below (ID map is not there because self-explanatory).

And the weathering generator node group inside Blender (identical instructions in Unreal)

It does look interesting. What’s the Blend Mode setting for the material? I imagine it’s Masked, but in case it’s not, how do you hide the seams between the main body of the object and the faces that contain the details?

There is no opacity, although one could use opacity for things like grates and fences for trims and floaters (in that case I’d use Masked). I’m not using decals that are floating above the other faces, rather using the faces that are already there (or cutting new ones into the mesh) to afford space for details. So it’s technically not the decal workflow but it allows for nearly all of the same freedoms as the decal workflow with some additional benefits.

The wireframed model below shows a circular floater toward the bottom. Its placement and size are determined by the geometry that’s there. To place it elsewhere on the model, I’d have to cut a square where I’d want the floater to be or use another square that exists on the model.

The reason why there are no seams is that the normal map, AO, etc. exist in a space separate from the grunge map. So UV0 is geometric hard-surface details, UV1 is grunge (simple unwrap, box-map, or you could even abandon UV1 for tr-planar projection).

The colors on the trim textures determine where the seams would be. So if the UV edge of a floater lands on a neutral zone (mid-gray for cavity map or white for AO) you never get a visible seam.

Here is another example of something you can do with this. Below I’ve nested elements inside one-another. The large face is bordered by the trim element, while the center has greebles placed within. Once again, the UV edges lay in the neutral zones of the trim sheet so no visible seams.

A more detailed use-case example. This time I’m actually using 3 materials with trim/greeble sheets attached. This is a lot of textures (10) for one object, however consider that just like the decal workflow you can get exponentially more objects that are tied to the same textures, so a very small amount of texture memory is consumed in the big picture.

@JamesCLight Thanks for the explanation and examples.

It seems to me the major downside of that approach is destructiveness and lack of flexibility. Since the geometry has to be cut to place the details, this process would require you to be fairly certain no changes will happen later to the position, size and rotation of the “decals”.

Yes the positioning is the downside when compared to using decals, as well as the need to uv unwrap in a more specific way. What I do in order to position my “decals” in specific places is to quickly cut a face and leave n-gons rather than loops across the object. If my design continues and I’d like to remove it or put it elsewhere, I just remove the edges and re-cut. Triangulate before Export. This happens to work well with both the weighted vertex normals approach and the support loops approach for medium-poly modeling.

I wouldn’t call it non-destructive, but I also wouldn’t call it destructive. Baking hero-assets is destructive, as one minor change usually causes a chain reaction which leads to hours of re-baking and re-texturing. With this approach I might lose 5 minutes if I want a few changes.

Interesting - how do you handle emissive decals that aren’t rectangular, e.g. circular lights? Say you wanted to add an emissive light on top of a face that has a custom normal on it, how would you do that? Thanks.