Downsides to using shared texture sampler source?

Just getting around to optimising my materials and wanted to know about the “Sampler Source” property in a texture sample, and can’t find any documentation about it.

I understand this can reduce texture samplers so is good for landscape when you run into the limit easily, but what about just using it in a regular material (where you are not necessarily hitting limits, you just want to reduce samplers to help the GPU)?

How does it work exactly? I’ve seen an Epic staffer on answerhub say “you can visualize it as kind of (sort of) creating a texture atlas in the background”, but is that actually what it’s doing? Does that mean it will create duplicate texture data if you use a “shared” sampler source on the same texture in multiple materials?

I guess what I’d like to know is: is there any good reason NOT to use “shared: wrap” all the time, as long as you don’t need to manipulate UVs on the sample and you’re ok with it using “world” filtering?

(This has implications for master material setup, so would be a good thing to know about from the get-go!)

The only reason we didn’t make Shared: wrap the default was to avoid breaking existing materials. There’s no downside to using shared samplers if the settings match what you want, only upsides. On AMD GPU’s used in the consoles, shared samplers are slightly faster as well.

Excellent, thank you for the quick reply!

I would like to know what exactly is the difference between separate samplers and a shared sampler.
Like Spoondog, I suspect that a shared sampler creates a texture atlas. Is this true?

When switched to Shared texture filtering switching to bilinear(or trilinear), I found no way to make it Nearest.

But what does that actually mean? I’m still not entirely sure what Shared Wrap is doing to optimize a material.

Quite an old thread - sure, but getting limits with number of samplers as well - and finding these** magic** settings, and these really help getting around the limitation.
But as PercepcualChange asks - what does that mean at all ?
E.g. Shared Wrap and Shared Clamp - what’s the difference here?
Even the marvelous Mathew Wadstein seems to be somewhat ‘unsure’ about that in his excellent tutorials, leaving out the real explanation.
OK, just to be sure anyway: going for setting *Shared: Wrap *now for every texture sampler node in all materials and material functions and not thinking about any implications (like a monkey) - is this the way to go?
What, if setting to Shared Clamp? Maybe I missed important stuff, but I did not find explanations (and did not do any experiments for now, I admit)
I always prefer to understand at least the basics before using some magic features.

A sampler is a GPU resource that stores the settings for a texture sampling (aka: reading) operation. It stores settings like wrap mode (clamp, repeat?) and filter (point, linear?). GPUs have a limited number of samplers that can be loaded at the same time (usually 16, but sometimes less on mobile), but you can re-use the same sampler resource to sample different textures in the same shader, allowing you to access way more different textures on the same shader than 16.

By default, UE4 assigns an unique sampler for each texture used by a material, so you can hit those limits pretty quickly. The “shared” samplers are two convenient samplers with two very common configurations (wrap and clamp, with linear filtering). If you have 30 texture nodes in your material and they all use Shared:Wrap, they are all using the same sampler.

6 Likes

Hate to bump this ancient thread but does anybody know exactly why Shared: Wrap doesn’t work on ES3.1 or Metal? Is this a limitation of the APIs or is it something that could be implemented in the engine but just hasn’t been high enough priority?

1 Like

Did you get any errors? Or your samplers still hit the 16 limitation when you use Shard:Warp?

It’s a 128 limit on shared.

1 Like

I apologize for resurrecting this necro-thread, but I have two good reasons for doing so. First, the fact that this thread still comes up first on a Google search of the topic (and reliably so, in my experience) suggests many people refer to this thread to solve the same problem. Second, I was motivated by this thread to do some further research and found resources worth sharing.

These were very helpful to me in understanding more about how the texture samplers work, and I hope they help others.

(The comments below are my own and should not be regarded as authoritative.)

Based on the sources cited above, my current understanding is that shared samplers are an effective optimization as long as the sampler state settings are compatible, and that there is essentially no downside to declaring Shared Wrap sampler mode in UE. The compiler will figure out what sharing is possible and revert to individual samplers if required, so some Materials may not benefit as much.

It was not clear to me exactly which parameters need to match for a sampler to be shared. For example, do the data interpretation modes (sRGB, Linear Color, Normal, etc.) have to match (probably)?

One question that I have pondered is whether the input texture coordinates (typically UV) have to be the same for a sampler to be shared. As I read the source articles, they do not. The sampler state would be shared, but each sample operation is (by definition) on a different texture, and the coordinates would be passed as part of that operation.

Thus, as I understand it, the use of multiple scaling/tiling or variation of UV coordinates would not introduce additional samplers and would incur only the multiple sample operations that are already required because of the multiple textures. If someone with graphics programming expertise reads this, please confirm or refute this assertion to enlighten me and probably many others.

I also plan to do some empirical testing of this and will update the post if I am able to confidently demonstrate one or the other behavior.

5 Likes

As far as I know, once you change UVs you create a new sample.

You can only affect UVs before passing them to the texture, which is why adding more copies of the same texture will consume more samples and cost more.

You are absolutely correct that changing the UVs creates a new sample. That is not the same as creating a new sampler, though.

As I understand the cited sources, the sampler is created based on the texture and is reused many times even if it only appears once in the shader graph. Consider that the UVs change with every fragment being rendered, so the overhead of creating a new sampler for every sample query would be staggering.

That said, I’m “somewhat confident” of my position but not by any means “certain” of it, so I will see if I can validate or refute my assertion experimentally. I’m definitely curious about this.

By the way, I absolutely agree that adding more copies of a texture or adding more textures would have a large resource impact. I don’t know if two or more independent samplers (for instance, with different wrap/clamp modes and/or channel modes) on the same underlying texture asset would imply multiple copies of the texture data or if they could share one buffer.

It’s essentially a direct X thing, so perhaps direct microsoft resources can better shed light…