In Unreal's Material Layer system, can I create a Material Layer that adjusts the saturation of the layers below?

Context:

I have an Arch Viz scene in UE 5.3, where I’m utilizing Cesium for Unreal to generate the landscapes around my custom-built environment. I’ve followed through this Tutorial on Cesium’s website to add material effects on top of the Google-generated landscape. All of that makes sense and works great when I want to apply overlay/highlight effects.

My issue is that the overall color of the Google landscape is a bit washed out, and I want to increase its saturation a bit. Only there isn’t a way (from what I can tell) to target its diffuse textures because there don’t seem to be any I can find withing the content browser. I have no idea how Cesium brings in and applies Google’s textures for the vast landscapes it generates. I’m guessing it’s some kind of procedural method.


So, to my question in depth:

Within a material layer, is it possible to create one that I could use to adjust the saturation to those below without sourcing a texture or anything? If so, what nodes could I utilize for this? Or do you have any ideas as to how I could approach this?

One thought I had was to source a 3 constant vector (color) somehow, but I’m not sure how to complete that connection to affect saturation and not just brighten things up.

I’m still learning Unreal’s material blueprint system, and it’s a vast set of nodes, so I’m drawing a blank here. Haha. All the tutorials I’ve found so far utilize texture inputs, which doesn’t help me much.

Thanks!

Responding to the title: no.

To change saturation you have to act on the layers themselves.
No other way to affect them since whatver you put on top is - well - on top…

Re the rest, probably forget cesium is a thing - and switch off the internet when the game is running, see what happens.

The material though, should have an input parameter as a texture object - but it could also be hard coded (and probably is, I wouldn’t bother making it accessible via unreal material editor if I was the one creating cesium) within the USF.
As such, you’d need to learn some HLSL and mess with the .usf that the terrain uses to bump up the saturation of the map.

Only other idea there is to hack the image at the router level
If you filter all images that pass thorugh your router from a certain address and mess with them from the router itself like any beginning hacker would do…
For instance by flipping them vertically so everyone in your house can’t use the interwebs for memes…
You can get the saturation you want, record a take, change the router back, and - assuming all you need is the take, you are done…

Mind you, hacking the router is easier than learning HLSL and editing a .usf :wink:
(Or you wouldn’t have script kiddos).

Thanks so much for you insight and feed back. I was worried that would be the case. Oh well, now I know.

Thanks so much!

That answer is absolutely incorrect.

You can set up a layer to desaturate any layers below it in the Blend Asset.

This is a basic setup for a Blend Asset that will use the Red channel of the top layer’s base color (you don’t have to use the Base Color, you can use any attribute of the top layer’s material you want in the Blend Asset. I just used base color because I threw this together in a couple minutes) to desaturate the base color of the incoming layer stack:

And this is the Material Layer that I’m using for the top layer:


(the saturate node is to cheaply clamp all the vector’s components between 0 and 1)

Here it is in action:

This is a super simple setup that just does saturation, but you can easily extend it to make essentially an ‘Adjustment Layer’ that you can drop anywhere in your material layer stack to tweak values of the lower layers.

[edit]Re-reading your original post I see you’re trying to increase the saturation, not desaturate. That graph is a little more complicated because you have to do RGBtoHSV conversion and back. Here’s what that looks like in the Blend Asset:

1 Like

Thanks so much Fafhrd! I’ll definitely be giving this a try!

BULL.

The landscape layers will never allow you to paint something that desaturates something else.

You can add, you can subtract.

That’s about it.

If you want to paint on top you can. That’s not altering the saturation levels.

Could you “use a layer paint that only affects all the layers after they are already combined?”
Maybe. Via custom layers.
If you expect to create a layer blend that does it for you you are SOL.

Go learn HLSL and write a custom node. Easier, more practical, and an actual solution since you can run desaturation or saturation algorytms you copy and paste with it.

Cesium doesn’t use the Landscape system, genius. It uses the Material Layer system, not the Landscape Layer system. Which you would know if you’d actually read the link to the Cesium documentation that Ken posted in the first post. And it’s also absolutely trivially easy to set up layers in the Landscape Layer system that modify other layers, either individually or combined.

First of.
Your example is even worse than non functional - you are affecting the whole material at once. Regadless of what or where the saturation should be increased. Which is not at all likely to be everywhere.

Secondly:
You can’t just saturate that way - its nonsensical.
You want to bias the saturation based on a color channel or a hue to achieve any sort of decent effect.
For example: fragment shader - Hue, saturation, brightness, contrast effect in hlsl - Game Development Stack Exchange

Thirdly.
Try it. You won’t be able to modify other layer by a layer if you use the landscape’s default stuff unless you: a) know what you are doing. Which you prove time and time again you do not.
b) use specific layer types, since blend will not work to override a layer. c) actually act on the correct output, and d) use a custom layer node.
Try it. See just how “trivial” it is.

Particuarly vs copy pasting code into a custom node.

Original Post Title Question: ‘Can I create a Material Layer that adjusts the saturation of the layers below?’

Short answer: Yes, obviously. As demonstrated.

Detailed question was:

the overall color of the Google landscape is a bit washed out, and I want to increase its saturation a bit… Within a material layer, is it possible to create one that I could use to adjust the saturation to those below without sourcing a texture or anything?

So yes, the example setup I threw together in five minutes doesn’t use a texture mask and just adjusts the saturation of the incoming layer. Which is what Ken was asking for. Any idiot can look at that and know to replace the Vector parameter with a texture parameter if they want more control over where the saturation is adjusted (or use the Cartographic Polygon masking method in the Cesium tutorial).

Thirdly.
Try it. You won’t be able to modify other layer by a layer if you use the landscape’s default stuff unless you: a) know what you are doing. Which you prove time and time again you do not.
b) use specific layer types, since blend will not work to override a layer. c) actually act on the correct output, and d) use a custom layer node.
Try it. See just how “trivial” it is.

I have tried it, it’s literally as simple as using a Landscape Layer Sample node to modify the attributes of a different layer. Like so (this is, again, a simple example using desaturation, but the same principal can be applied to literally any material attribute by using the weight of the adjustment layer to drive lerps instead):

Ken will know what to do based on what I had initially shared and be further helped by the subsequently shared HLSL.

Keep in mind evrything else mentioned is pretty much flat out wrong, so think twice and run tests before you compromise your projects with it.

Thank you so much for your solution. I finally had time to try it out, and it worked great!

I’ll definitely be looking more into this so I can add other adjustment controls and turn it into more of a fully adjustment layer like you mentioned before.

If you don’t mind, could you kind of explain real fast the breakdown in the image showing how to increase the saturation?

  • I understand the RGB to HSV, then breaking them apart.

  • But why for the “input top layer” do you only mask the ( R)?

  • why do you multiply it by the (G) of the lower layer then add it to the (R) & (B)?

Again thanks so much for taking the time to help!

Hey man! I appreciate your assistance but I think you may of gotten mixed up with my question and what I was trying to achieve.

I did exactly what Fafhrd recommended and it worked just as he described. So I can confirm his results as well.

I think it was just a big misunderstanding is all. But still, thank you again for your input!

If you are talking about the material saturation, it may apparently work (with material layers i assume) but its not ok at all performance wise.

Goes back to not doing mental gymnastics to add 2 and 2 togeter.

If you directly affect the texture before the UV is part of the equation there is near 0 performance cost.
Almost like if you had plugged in the correct texture.

If you mess with stuff at the UV level, then - particularly when it comes to landscape - you end up with nothing working and 2fps.

The dude is a jackass who’s already costed 3 people 3 months of work to recevoer from his screwy “solutions”. Be careful what you implement - and for what purpose.

A screenshot is obviously fine with 0 performance - a game levaraging Cesium is definieltely not…

Citation needed.

I’m using the Red channel of the top layer’s base color to control the saturation in order to leave the other channels free for other controls. After doing RGBtoHSV, the Green channel of that result is the Saturation channel, so multiplying R of the top layer by G of the lower layer’s HSV conversion adjusts the Saturation, and then it has to be re-composed into a Vector3, R(H) append-> G(S) ->append B(V) before converting back to the RGB colorspace.

In your use case.

If the R channel is 0 you get what?
What is 1 * 0?

Lets see if you are able to put 2 and 2 together…

Once you realize you are wrong,
Have a look at HLSL code for the proper way you should do the saturation bump.

Just because you can simplify something, doesn’t mean you should, unless you have some kind of certainty that a result will avaliable;
Using a random texture (which may not even load btw) doesn’t give you any kind of assurances for that R channel.

Additionally to that, you are clamping the result - which isnt wrong, but what is 1×1 ?
And what is .1 x 1 ?
Or the commutative property of the multiplication?

Even just logically without knowing math:
“Hey system, do Y * X, and then just dump all the stuff thats above 1.”
Is that logical?
No… Maybe Normalize would be (if you also had something that factually took the values out of range):
“Hey system, re-adjust everything so that the highest value you got is always 1 and everything else is scaled down appropriately”.

Anyway, the point is: the code is wrong.
The HLSL is not.
Implement a custom node with that directly if you don’t care to learn.
Then your solution could work - if you overlook perfance concerns entierly.

Ah, okay. You don’t know how colours work. That explains a lot.

If the red channel is 0, the saturation is 0. Which means the texture is fully desaturated. If the red channel is 1, the saturation is whatever the saturation of the sampled pixel of the texture is. It’s clamped to 1, because making saturation greater than one will break the colour.

“Hey system, re-adjust everything so that the highest value you got is always 1 and everything else is scaled down appropriately”.

This would result in a saturation adjustment that does next to nothing. The whole point of adjusting the saturation of a texture is to adjust the saturation, not “keep relative saturation levels of all the pixels exactly the same.”

Re-read what I wrote about math around 100 times.
maybe it’ll sink in.

And if you think that normalizing means keeping everything the same, I mean… there is really no point in trying to explain things to you. Nicely or otherwise…

Apparently you need some visual aids to understand why what you’re saying is dumb. I’m going to use Blender because the Compositor has a node that normalizes the value range of an input texture.

Here’s an albedo texture from Megascans:

Here’s the HSV Saturation channel of that texture:

Here’s the NORMALIZED Saturation channel:


Weird. That looks EXACTLY THE SAME. Must be because there’s at least one pixel with a Saturation of 1, and one pixel with a saturation of 0. Which you’d probably get in every texture or image that has ever existed.

Let’s multiply the saturation by, say, 100, before normalizing it.


Whoa, crazy, it’s still EXACTLY THE SAME.

Let’s see what happens when we recompose the HSV with this multiplied Saturation.


Whaddayaknow, it’s EXACTLY THE SAME AS THE ORIGINAL IMAGE.

Let’s do something crazy and clamp the multiplied Saturation before we normalize it.


WHOA, The colours have actually become more saturated! We get some yellows and reddish browns that we didn’t have before. The only pixels that haven’t changed are the ones where the Saturation of the original image was 0. But that’s fine, because when Saturation is 0, Hue ALSO changes to 0, so we’re left with Value.

Now let’s drop the normalize


Yup, the same as it was with the normalize.

Just for funsies, let’s turn off the clamp.


That looks kind of broken, actually. Those yellows and reddish browns that we got have now turned dark red. Maybe having Saturation greater than 1 is bad, actually. Good thing we can clamp and prevent that from happening.

And one more just for fun thing, let’s multiply the Saturation by 0


Oh no, that dastardly math has struck and fully desaturated the image! Almost like someone would absolutely expect to happen!

I don’t think we needed you to give us examples of stupidity, but its nice to know that even after changing accounts you are still able to double up on that like you did for the previous account. :wink:

I wonder just how long itll take you to get this account banned as well now that i realize it can only be you :laughing:

Actually, I’m almost impressed you don’t just claim to currently work for Blizzard, EA, Bioware, or Epic themselves (again)!
Your knowledge, and mostly your reading comprehension, seems to be about on Par with the same persons who bring you things like Veilguard’s super accomplished narrative!
Really, keep it up, we absolutely cannot possibly do without the comedic relief you bring to this forum again. :laughing: