Issue with Material Instances (both Constant and Dynamic)

Hi, everyone!

The UE documentation clearly says that:

  1. You should make an Instance of your Material if you wish to customize its parameters individually for achieving multiple looks, as the base Material can only have one global/default “version”.
  2. A regular (Constant) Material Instance can only be manipulated via the Material Instance Editor, but if you wish to do this in-game (at runtime), you should make a Dynamic version of it so that you can change its parameters through BP or C++.

Well… I found out that not only can I change everything I want at runtime without the need of a Dynamic Material Instance, but I actually don’t need any instance at all. UE allows me to do everything, at runtime, by using just the parent Material itself, with no other tricks or exploits whatsoever. Simply use a Set Material Value node from BP and it works! I even made a video, so that you can see exactly what I mean: https://www.youtube.com/watch?v=obGUpl2w7fw

Can anyone please explain to me what’s going on? Why is this working in the first place and why is the documentation clearly saying you cannot do this without a Dynamic Instance, while in reality you can do it without any issues?

Thank you so much!!!

Notice the mouseover hint

and the ‘s’

This is for skeletal meshes, I guess.

I don’t know, but I think you’ll find setting params on a bare material like this, very inefficient with large numbers of meshes?

Untested… :slight_smile:

1 Like

This is how it has always worked as far back as I can remember…

I’ve never read that bit of the documentation, but it makes me think of the obvious question: Did you try this in a shipping build? My first thought is that it may be that material instance constants are built only during packaging to reduce shader permutations during development.

1 Like

Unfortunately it also works with a shipped game. I’ve built & exported everything under a package with the “Shipping” settings applied and when I run the created .exe the same thing happens: everything works perfectly :face_with_monocle: This should NOT be happening according to their own documentation and every other tutorial on YouTube out there…

Did you test with a non-dynamic material instance or just a regular material? The regular material, I expect would work fine. I’m more curious about the “material instance constant” as it is something I’ve never heard about until today.

Also, be aware, that this

image

is not shipping :slight_smile:

It’s a little perk that Epic decided to include in 5. If you can open the console, it’s not a shipping build.

The only way to make a shipping build, is with the launcher

image

2 Likes

@Arkiras yep, I have tested with the Material Instance as well. I also didn’t know about the difference until I saw a tutorial, and since that didn’t make sense from my experience, I went to the documentation, which indeed says that I shouldn’t be able to do any of those things (controlling a M or a MIC from BP/code without using a MID).
@ClockworkOcean that’s the only way in which I’m packaging, through the project launcher! :+1: So, indeed I’ve tested it with a Shipping build, a true one. And unfortunately, everything works as it shouldn’t :slight_smile:

At this point I’m not even sure what to do, who’s wrong or right. Did Epic just put that in the documentation for no reason and made people use a MID for no reason, when all this time you could’ve just done it without, by using a MIC or even M directly? Is this a bug or a feature?

M = Material
MI = Material Instance
MIC = Material Instance Constant
MID = Material Instance Dynamic

Source: the documentation

1 Like

I doubt it’s a bug as like I said, this has been the case as far back as I can remember. I’ve always viewed material instances as a workflow optimization, and I only used MIDs when I needed unique instances of a material.

This may only affect certain platforms (or some other context which is not mentioned), but most likely I think this is just something that affected the earlier versions of UE4, and the documentation was never updated.

Discovering docs pages that are out of date, lack useful context/detail, or just have incorrect information or important omissions is always demoralizing, but unfortunately it isn’t uncommon.

@Arkiras That’s exactly what confuses me at this moment, cause as you can see from my video, I’m perfectly able to create unique looks for different objects without having to make any MIDs, actually not even MICs (I only use the raw parent Material, which can be endlessly customized without the need of any Instance, be it Constant or Dynamic).

I do not think this is a case of purely outdated documentation, as the MID and MIC blueprint nodes are still there, you can work with them from BP, so they’re still active as though they’re meant for something you can only get by using them alone, yet they are apparently redundant in behavior (or the parent Materials found a loophole and they’re now able to function like Instances, regardless of Constant vs. Dynamic).

Why would they go through the trouble of making Materials, then Material Instances, which then split into Constant vs. Dynamic, when you can do everything by just using Materials alone, from the get-go? I am still unable to find a single use-case where Materials are not enough and you need Instances of it, let alone Dynamic ones over Constant.

You can’t make a master, apply it to 5 cubes, and then change them all to different colors?

You at least need instances :slight_smile:

Ah

image

didn’t see that…

Seems you’re correct, I tested in 4.27 as well and it works (at least in PIE, didn’t bother with a shipping build, I just assume it probably works fine)

It does have some workflow benefits. It’s a hierarchy, meaning you can make a change to the parent and it affects all the children. In a toy project like this it’s no big deal to make everything its own material but in a real project with thousands of materials, making low level changes will be brutal without a parent/child relationship.

It also conceals the material logic from artists who might otherwise be tempted to ■■■■ it up.

:person_shrugging:

@ClockworkOcean I actually did that in my video, I just used 1x master (parent) Material, with no Instances whatsoever and as you can see, I was able to individually set the Color, Specularity and Roughness to both objects. That clearly shows you can modify the same Material with different parameters, at the same time, for multiple objects, without the need of instances.

@Arkiras The fact that I’m using only 1x master (parent) Material actually still grants me the same workflow benefit :smiley: But I know what you’re saying, so ok, let’s say that Material Instances do have some use as far as workflow goes, especially for artists, masking away the implementation and only exposing the needed parameters. BUT the whole Constant vs. Dynamic thing is still a huge mystery, as the MID overhead is quite big and at the time of writing this, we both see it makes no difference in either UE4 or UE5, as you can do the same thing with MICs directly, without converting them to MIDs.

I just asked a bot, it said

:slight_smile:

This sounds like a disaster, but that’s a different topic :U

I’d also like to know what the deal is with M/MIC/MID so if you figure it out, please update us

@ClockworkOcean Hmm, first of all, where did you get the Bot from? I want to use that as well :smiley: Second of all, his first paragraph tells me that a MI (which, by default is a MIC according to the documentation) is better than a MID, while the second paragraph concludes by saying that a MI is better than dynamically changing the parameters of a single material (which implies the regular, non-instanced parent Material). I think it confused 2 very different concepts due to the subtle wording difference: dynamic material instance (MID) vs. dynamically changing a material (M).

@Arkiras I only used 1x parent Material to prove that it can be done, not saying it should be done like this. But as long as the docs and all YT tutorials out there are saying it cannot be done like this, when I’m clearly showing that it can… this thing really bothers me… :face_with_monocle:

1 Like

@ClockworkOcean I took a closer look at the documentation and had to go back to the hints you dropped in your post. Please, let me know if I understand this correctly… When we go to the node doc, we see the following (notice the Italic font):

Set Scalar Parameter Value on Materials - Set all occurrences of Scalar Material Parameters with ParameterName in the set of materials of the SkeletalMesh to ParameterValue. Target is Mesh Component.

Does this mean that the drawback of using this method is that:

  1. it only works on Skeletal Meshes?
  2. if my mesh has more than 1x Material applied and by coincidence I have the same parameter name in 2x or more materials, it will automatically set all of them to the same value in bulk?

Cause that might explain why my solution would have some drawbacks, although it still doesn’t answer my earlier question from the last few posts (why we’re able to do this despite the docs saying only MIDs can change things during gameplay at runtime).

1 Like

1: No

2: Yes, I would think.

I think it’s a little bit like ‘get all actors of class’, but ‘get all materials on mesh’

:slight_smile:

1 Like

Back with some updates. Just when I thought I’d be able to solve it, I ran into even more things that contradict the documentation, as well as common sense :slight_smile: As tradition would have it, I made a Part 2 video, explaining everything:

If you look at MeshComponent.cpp and look for:
void UMeshComponent::SetVectorParameterValueOnMaterials(const FName ParameterName, const FVector ParameterValue)
you will see that the code for the “Set Vector Parameter Value On Materials” BP node actually creates a MID :

UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface);
				if (!DynamicMaterial)
				{
					DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex);
				}
				DynamicMaterial->SetVectorParameterValue(ParameterName, ParameterValue);

so to make it clear: by using this method you are not editing the Material/MIC directly.
the documentation is still correct, it’s your conclusions that were skewed by this fact :slight_smile:

4 Likes

Just for reference, in case anyone wonders what node you’re talking about in the previous post, it’s this one:

image

Hmm, very interesting… I was hoping that would ultimately be the solution, as the only possible explanation in my mind would have been some sort of implicit cast or similar things happening behind the scenes. This would also explain why I’m able to retain the behavior separation when editing the Material directly (or so I thought) for multiple meshes and why this doesn’t happen when explicitly creating 1x MID that then gets used by multiple meshes :+1:. I hope the reasoning of this last statement of mine was sane enough this time (boy, oh boy, I just made a rhyme :smiley:).