Developing UE4 Materials for VFX

Thats exactly what you’d do in a material instance, if your master material is set up properly though, and no need to compile a bleepload of shader instructions again.

You’d only go back to the master material to add functionality, and lets be honest… after a few projects you can basically copy/paste most of it as a proper master material would work in multiple situations.
By now I have one master material for my vfx I could use in 80 - 90% of situations, regardless of theme, style, etc, and due to proper usages of instances & master instances the instructions and recalculations are extremely low.

That said, thats what I’d do for big productions.
If I just make stuff for myself, or fast prototyping, id just drag & drop a few nodes + MF’s to get the result I want.
Also, and probably also very important, is that in my case I do mostly fantasy/magic kind of vfx, as realism (bullets, regular explosions, muzzles, etc) bore me to death.

If you go the master material route, you should put everything behind switch parameters, and default everything but just the texture multiplied by particle color and opacity as False/Off. Then just turn on what you need per instance. Usually you can use a master material for most things, but keep flexibility for custom materials if it’s something you can’t achieve with your master and it’s going to be awesome! Try and keep your more inherently expensive materials cheap in instructions and node complexity. Things like Volumetric Directional lighting for translucency is expensive, but actually makes use of normal maps for lighting your particles, so we use it almost exclusively for smoke, and only when it’s going to be persistently on screen. It’s just 3 texture calls and a few multiplies, and a dynamic parameter for flow map control.

Fun fact: comment boxes can help you keep your materials organized, but you can also change their color as well!

For materials on meshes, make sure to include vertex color in your material, and use the SubUv texture node instead of the standard if you want your flipbook to run on your mesh.

I generally try to make and use material functions for things that take up a lot of screen space, just for organizational purposes.

One last thing, if you are going to make a master material, always, Always, ALWAYS, give every parameter /parameter switch a unique name. I can’t tell you how many times something didn’t work as intended because Texture_Pan_X was used twice when I should have numbered them as well. Switches can really test your logic choices when you are hooking them up, so always be prepared to iterate and refine how things are organized.

4 Likes

Category names too! Nothing worse than having a thousand parameters all under default.

3 Likes

+1

This, 100%. Helps keep your material instances organized

2 Likes

Wow, all of this is extremely helpful! Looks like I’ll have a lot to mull over in how we approach things. I hadn’t even considered Material Functions, so I’ll be looking into that as well.

After 42k recompilation several times in landscape and player building master cuz of function changes I tend to avoid functions. Id rather keep some copy paste code in some old file and paste it in small materials. I cant imagine making vfx without opened material editor… But thats just a habit. Funtions can be sometimes. replaced by render2texture… I just made wind system that render small tilable texture with direction and power and just sample it in grass bushes and trees. That replaces some nasty and heavy functions…

From my experience, I tend to agree with @alex.underhill on this one. I am a fan of material functions over monolithic master materials these days, excepting in cases where you know you can get a lot of mileage out of a single master material.

A good example of that would be something like “flares.” Most of us have authored about a million and one flares for particle systems, and because they are going to be so widely used it makes a lot of sense to have a single master “flare shader” that has a lot of behavior sectioned off via switches and material instances that change those behaviors.

Going with master shaders for your really common building block (flares, sparks, smoke) and one-off shaders for things more specific seems to be the method I end up falling into. Of course at FXVille we are nearly always working on teams with existing practices, so by far the best thing to do is to do what the other artists are comfortable working in. :wink:

2 Likes

This is a great mention and a really important point that I think lots of answers (including my own) have glossed over!

Master materials have huge advantages in terms of fewer draw calls, better sorting, and optimizations that propagate throughout the entire game, but this absolutely does not mean that 100% of your effects have to use this shader! Let your master shaders handle 85% of your effects, and go nuts on custom shaders for those other 15%. “Default shader” might be more of an apt term than “master”.

I’m just stressing this point since I’ve met lots of artists coming from UE4 with a “One shader for one emitter”-kind of mentality, which can quickly create lots of issues.

I’m adopting this approach.

+1 for that. that exactly what I meant in my first comment because they make materials and not shaders.
its messing two definitions and shader developers won’t recommend unreal mentanilty :slight_smile:

Master materials have huge advantages in terms of fewer draw calls, better sorting, and optimizations that propagate throughout the entire game, but this absolutely does not mean that 100% of your effects have to use this shader! Let your master shaders handle 85% of your effects, and go nuts on custom shaders for those other 15%. “Default shader” might be more of an apt term than “master”.

I’m just stressing this point since I’ve met lots of artists coming from UE4 with a “One shader for one emitter”-kind of mentality, which can quickly create lots of issues.

+1

Also, material parameter collections! FTW!

I am not sure if master material is considered 1 shader. If U got many switches - every other combination got its own shader in memory. So there is no gain in that. But I d like to ask some expert in unreal4 1st :slight_smile:

From the initial responses, this was what I was leaning toward. Glad to see you and others reiterate that line of thinking!

Anything that doesn’t change due to a switch doesn’t need to be recalculated.
So if you have multiple switches, its best to make a material instance for each potential switch setup (or better yet, only for those needed) and use that material instance as a “Master Material Instance” that way any instance that derives from this one doest need to recalculate the switch-changes.

You could see it as “branching”
Example: Screenshot - b50e13d4f3a91165ef5b49e8fa87a0ae - Gyazo

I personally might even start with a material instance to derive from instead of a master material, so any tweaks that need to be passed onto all the branches can be done in the instance to save some time.

that way I only need to go to the master material when its really necessary to tweak/adjust nodes.

As long as material instance is my base I see no gain in that. It is harder to spot a bug. it is in both cases separate shader in memory. There is a risk of not needed code. Also for fast tweaks and optimization it is easier to do it on material than to switch to another material instance or change its root. I personally saw big project on ue3 shipped to consoles and pc with even env shaders separated to each mesh :slight_smile: Every approach is good as long as U are smart about it.

Untill your boss/client/lead tells you that they need a specific new node/material function/feature in ALL your effects (or anything really) and you need to manually add that into each material, instead of one master material and a handful of special cases.

Ive been there, and spending a day adding a new feature to almost 300 materials (I came into the project late, else this would never have happened) is not only mindnumbing frustrating, its also expensive. (time = money spend)

Also FYI: They are not seperate shaders in memory, any calculations done in the master get passed onto the instance.

That[quote=“Luos_83, post:24, topic:1035”]
Untill your boss/client/lead tells you that they need a specific new node/material function/feature in ALL your effects (or anything really) and you need to manually add that into each material, instead of one master material and a handful of special cases.
[/quote]

That never happened to me in entire career. In Unreal U would just walk to programmer and add it to material class. And then disappear for a day not to feal wrath of 100k compilation for entire team.

Check in PIX or any other profiler. Only case when object dont reload shader is when U switch between 2 instances with exacly the same root. If only there is 1 switch changed - new shader is loaded.

Even in manual there is written: “a new version of the material must be compiled out for every used combination of static parameters in a material”

Wow, this is a very interesting topic. :slight_smile:

To support what @Marcin_Kazmierczak is saying, we are also working with a custom Ue and I’ve been told that a Master materials that has plenty of switches is basically (under the hood) the same approach of having multiples master materials since a new shader is created for every possible combinations.

As you guys said, it ends up being the technique you guys prefers for your workflow. Best case scenario I would also avoid the one master per particle emitter for reasons already been discussed but I like the philosophy of building one simpler master per type of effect so far (combined with function usages like @alex.underhill is suggesting). It’s easy to maintain and fast to iterate. The counter part is like @Luos_83 is explaining, it may be a pain to revisit all of them if needed. So far it has not been a major problem on our side but we already had to revisit a couple of master materials to add some functions.

So far, this means around 40-60 pretty simple master materials (they have few static switches inside them if they have any) to covers all of our VFX needs. ie: Flares, Smokes, Fires, Lightnings, Birds, Dust, Water splashes, etc.

I know that the number of shaders created could become a problem at some point. I guess because I don’t have the precise numbers for the specific VFX related shaders created it could create easily hundreds of shaders with all the changes in the materials instances. We are trying to find ways to have more precise numbers on the shaders created with our Materials. This will help us be a bit more responsible to really try to re-use before customizing a new material, material instance.

I heard that BF1 were using only 10-15 masters materials (can’t find the source info so I’m might be completely wrong here), I’m wondering if they were containing a lot of static switches that would anyway also generate a lot of shaders combinations in the engine or maybe they made the exercise of trying to make the most out of the fewest materials/shaders possible? That said I also know thet they don’t use the same tech so the workflow may be quite different anyway…

One thing to watch out for with static switches though, is that each branch is still compiled as a unique shader when you cook the build. If you have thousands of assets, all using switches, it can really bloat your shader overhead quickly.

We just ended up doing a pass on our props to remove all switches and go with prebuilt variants of what all those switch options represented as master materials. You’d think this’d be the same cost, but it’s not, it drastically reduced our shader compiles and memory use. It also had the side advantage of letting us form a custom texture packing scheme for each variant, to save on texture memory.

VFX usually doesn’t have the same issues, more standardized material use cases and less overall asset counts, but in a large project it can hit the same problem.

1 Like

Thanks for the info. I always enjoy learning more optimization tips and tricks. I’m sure there are some things we can cut down to their own materials, but we use probably 70% of our master materials functionality for most particles, in some capacity.

By that you mean only the used combinations, right? This is in the documentation:

“On the other hand, a new version of the material must be compiled out for every used combination of static parameters in a material, which can lead to a shader explosion if abused”

If it compiles all of the possible variations, even unused ones, then I’m screwed :confused:

1 Like