ID map and RGB mask for layered material multiple surfaces

I have made a Layered material

I want this model to have 3 different materials. The black plastic, a small metal piece and the front panel of this mesh to be made of glass. However I also want to keep the dust and edge scratches on the different surfaces (plastic, metal, glass). The edge scratches are driven by the cavity map in the green channel of the RGB mask.

I have a M_Master material.

I then have a master ML_MaterialLayer_Base

Finally I have a master MLB_Base, to blend using my RGB mask

As you can see, right now I have 3 layers.
Background (black plastic)
Wear layer (wear and tear, scratches) using the green channel of my mask
Dust layer, using the blue channel of my mask

Thats all cool, however. How can I apply a different material / surface to the glass?
I assume I need a new type of mask, one with color ID’s instead of stuff like cavity, dust etc packed into the channels.

I can make the ID map, no problem but I’ve got no clue how to actually set it up. I tried looking at a few threads and the official Unreal wiki and videos but didn’t find a result.

If I make a ID map and say Green channel is glass, then it will override the scratches from the other RGB mask containing scratches (G) and dust (B). Or I would need to stack the same stuff on top of each other again like so

Background layer
plastic layer
plastic scratches layer
glass layer
glass scratches layer
dust layer

but I want to do this basically

Background layer
plastic layer
glass layer
scratches layer (entire model)
dust layer

I hope this is understandable? Any help or info pointing me in the right direction would be much appreciated

you could use vertex color to drive the seperation of the plastic and metal. you can not include the glass in this material tho. if it’s translucent it’s gonna need a different material and shading mode.

Thank you for your input :slight_smile:

I see, but my question would still stand as I plan to do a lot of props, some without glass so i’ll still run into this issue.

For example a Sofa with surface X, pillows with surface Y and sofa legs with surface Z.
Could be leather, fabric and metal.

Vertex color i’m not entirely sure what you mean by that, these props are also fairly low poly so not a lot of vertices. But I just assumed a simple ID map should do the job no?

Again i’m using a layered material workflow, so i’d like to make it work with that but perhaps i’m misunderstanding what you mean exactly.

the layered material with the different material layers

So essentially, you cant.

You need to either split off the material at the object level, creating a new naterial slot, or - and this is likely better - make a hole in the mesh. And attach the glass as an entierly separate mesh part.

Why?
Because the engine rendering sucks, thats why.

Glass has to essentially be forced into forward shading for things to work, and even then, with TAA on you will surely get some artifacting.

At the material level, you have to set the transparency shader you want, then you have to also apply a proper fresnel driven IR index value, and adjust tint and other info.

The mesh for glass also generally needs to be double (2 sides, without 2sided, because the engine won’t support a single 2sided transparent plane all that well).

The same is also true for pretty much any transparency in engine, plastic or stained glass alike.

Oh. On top of that. The engine will not really allow you to priority sort transparencies, so you also have to avoid mixed structures that involve transparent materials whenever possible.
(So if you make a fridge with a french door, and the door opens revealing another 2 doors that are transparent, you probably need to merge the 2 doors into one object to get the correct output).
I mean, you can do pixel depth checking in the shader to sort it out - like custom water - but its stup1d expensice for something as simple as described.

I’m sorry, this was just an example prop that I wanted to seperate into 3 different surfaces, Plastic, Metal and Glass. I see now this might have been a bad example prop.

My main problem isn’t the glass itself, it’s making this layered shader work correctly. It could have been another prop such as a chair, table or Sofa.

A sofa could be 1 mesh with 3 different 3 surfaces all combined into 1 layered material.
Leather surface for the sofa, Fabric for Pillows, Metal for the legs.

My issue is right now I have a Layered Material that is able to use a Detail RGB mask to place stuff such as Dirt, Dust, Edge wear, Scratches etc on top based on the R G B channels.

However, it’s doing it on the entire mesh via the Green channel for example where I packed in my “edgewear/scratches” for the model.

So if I say the “wear” layer is using the green channel in my mask, all edges and some scratches will show up. But on the entire model, so if I have metalic scratches it will also show up on the leather and fabric portion.

What I want to somehow do, which I think is the correct way to go about it is to have a “base” bottom/background material and the bottom of the stack.

This material should have different surfaces applied to it, via an ID Map. Leather, Fabric, Metal.

Now the layers on top, above such as edge wear, dirt, dust. Each one will be applied on top of the base. But on apropriate surfaces, so I don’t have metal scratches and edgewear on the leather and fabric.

I’m really sorry if i’m rambling, i’m just trying to make a “proper” layered shader that I see being used in the industry.

This way I won’t have to use 100s of unique textures for 100s of props, I just have a library of materials such as leather, fabric, metal, wood, plastic.

And then I can apply rust, dust, dirt etc on top. But obviously I don’t want to apply rust on leather or wood.

I hope this is making sence what i’m trying to accomplish?

lil demo Adobe Developer Summit: The Material Art of 'The Last of Us Part I' (Presented by Adobe) check 17:40 and 32:50 how it is applied. it’s basicly a per vertex id mask, not a texture or anything. at fully rgba you can differentiate 5 materials. there are alternatives too. you can use secondary uvs and small atlases to determine properties or blend parameters for materials. basicly abuse what ever data channels you have to id or blend materials per vertex.

this is the other one you might be interested in. a complete rundown howto crunch grime layers. https://ubm-twvideo01.s3.amazonaws.com/o1/vault/GDC+2021/33713_GDC-2021-MatthewTJohns-ND.pdf

Ah yes, I see now. Thank you for the video, i’ll definetly be saving that.

However, this seems to be vertex color painting. It works well and i’ve used it before or similair but it’s not exactly what I want for this. This seems better for flat surfaces and environments.

I don’t want to be painting manually on 100s of props if that makes sence, I just want to export mask for prop A, prop B, prop C. (chair, table, sofa) and have the dirt, rust, dust etc be controlled by that mask. Dirt in Red channel, Rust in Green, Dust in Blue for example.

This video kind of shows something very similair to what I am trying to do.

at 05:22 he is showing a mesh with different surfaces, grey metal, gold etc
at 06:15 he shows the ID mask with Red Green Blue for the mesh
at 13:30 he is showing a model, with a layered material.

It has a “base” layer which is the texture for the model, albedo, roughness etc. Then it has layers added on top via material layers. Top Dirt, Rust, Grime, Moss.

Now basically what I want to do is have that bottom base layer have seperate surfaces for wood, leather, metal etc based on a RGB ID map. Because in their example they are exporting a 1:1 unique UV’ed texture. I want it to just use tilable ones and then a ID map to apply it to different portions of the model and then layer the rust, dirt etc on top via material layers.

their model from the video with the base layer and layers on top.

Your “wear” is everywhere because all the layers use the same object UV?

I want it to be all over the mesh, but I want the parts to be different depending on if it’s wear on the metal or leather or wood.

I might have been going too complex with the layered material approach, I tried making a new simple material.

All I want is to be able to have 1 single material with 3 surfaces, based on ID map.
Then I want a detail map for the dirt, dust, wear. But I need it to cover the entire mesh (uv2) but look different depending on the surface. So no shiny metal wear on fabric.

I guess I need to either isolate the detail map based on the ID map somehow or have individual parameters for each layers detail/scratches

Here is my new very basic material, i’m just trying to make this as simple and as optimized as I can.

Surface controlled by ID map

the detail map, red for dust, green for wear, blue for dirt

Here is the albedo node set up, 3 diffuse textures. Each applied based on the ID map

and finally here is the full material setup

Now everything works except I don’t know how I can have the details show up and be different for each layer when it comes to roughness, color etc.

that doesn’t look too bad for manual shader setup. this is basicly what layered materials doing under the hood. i tried to read the documentation this morning. a lil bit confusing tho. hmm…

Thanks, i’m pretty proud of my quick little shader too haha

I wonder what is best, using something like this or the built in layered shader.
Even with just 2-3 layers in the UE layered shader, the shader optimization view shows it as red while mine is still in the green as of now.

i dunno tbh. you gotta test real performance with a kinda built level. put some amounts of those props in there. i’ve only rebuilt parts of nd’s car shader. it was green too, yes. and never tried the layered stuff. i know for a fact tho, substrate (which is the next iteration of this) runs like cr*p on my rig. single digit fps in the demo map. yeh…

Ok…
Drop the “id map” idea.
Meaning RGB as individual channels.

Get some HLSL into a custom node. Ferd it the RGB input, and have it spit out up to 8 layers (possibly more) defined by areas of color.
(You can also think of it as single channel being 25% white, then 50% then 75% etc but designing the texture maps is nightmerish).

Then, define what is what - for instance, I have ff00ff as cloth ffffff as metal, 00ff00 as leather etc.

With that, and the output off the HLSL code you can drive everything at a rather snappy/low cost.

You can find the Epic made functions to define the color mapping like this as part of the Physical Material definitions.

Or, ofc, you can google it.

Or you can go at it yourself.
Afterall a simple if like
if (color.r == 1.0f && color…g==1.0f && color.b==0.0f)
Ourput 1.0f

Is what you are after here.

Super simple.
Once coded righr, with If > else, because of the custom node it will also be Branched for you (so that unless you connect an output the IF doesnt even run).

Now with that, you just lerp.

And yes you do have to make material > break material > lerp > make material again if you want to define it as a reusable function.

Hoever, you do need to keep in mind that you should not be exceeding 16 total texture samples overall.
That’s usually
1 color, 1 normal, one PAKED(R roughness, G specular, B custom stuff, A opacity)-> per layer

  • 1 overall texture for layer mapping.

Should be up to 5 layers per material this way. Without forcing Shared Wrap (which causes performance loss in potatoes or inability to run things in DX9 for instance if one is so inclined [yea not via unreal 5 obviously]).

Anyway, back to your question; re read the above.
Pack your detail into the custom packed texture channel. Use that channel to output the detail solely based on the layer type.

Problem solved :wink:

1 Like

Thank you so much, something like that is what I think I was looking for.
I’m really sorry with the late reply, I’ve had a busy new years and lots of work :slight_smile:

I will try to do this as soon as I can and see how it works, thank you again for being so helpful :smiley:

1 Like