- Home /
MaterialPropertyBlock causes Z-fighting sprites
Hello, I'm trying to use a MaterialPropertyBlock
on a custom sprite shader, but it seems to be causing Z-fighting any time a value is modified inside the MaterialPropertyBlock
.
As you can see in the following gif (gif 1), every time the color of a sprite is modified it jumps to the front, and back, flickering like Z-fighting. To be clear, yes both sprites are on the same Sorting Layer, and Order. However, the default sprite material with the same configuration doesn't flicker and looks like gif 2. gif 1: using MaterialPropertyBlock, changing a value causes flicker
I tried using a basic material with the same shader applied and it doesn't have any flickering problems. So the problem definitely has something to do with the MaterialPropertyBlock
. gif 2: using basic Material works perfectly (but inefficient)
So my question is: am I'm using MaterialPropertyBlock
incorrectly? Is this is a known artifact? How do you deal with it?
SpriteRenderer spriteRenderer;
MaterialPropertyBlock mpb;
void OnEnable()
{
spriteRenderer = GetComponent<SpriteRenderer>();
mpb = new MaterialPropertyBlock();
spriteRenderer.GetPropertyBlock(mpb);
}
void Update()
{
mpb = new MaterialPropertyBlock();
mpb.SetColor("_OutlineColor", OutlineColor);
spriteRenderer.SetPropertyBlock(mpb);
}
Posting this as a comment since it doesn't really answer the question exactly, but...
It looks like you are using $$anonymous$$aterialPropertyBlocks right. At least, that's how I use them and it works just fine for me. I mostly work in 3D, but I am fairly certain that the way it works in 2D is that, if no method of ordering is specified, it just takes whichever is first on the list to be rendered. Ordinarily this list doesn't change, but if you are doing something like instancing (which I'm assu$$anonymous$$g this is for), or something that might be batchable rather than always be unbatched, it can. Your flickering looks like render order being moved around very fast, since it occurs over the entire sprite uniformly.
As I said, I don't really have a 'real' fix for this, but would it be possible to simply change the ordering explicitly through script while it's animating to be rendered first (and behind), then bring it back into the normal ordering when it's done? If you are instancing these, consider perhaps instancing them in explicit clusters rather than just doing it automatically. It's most certainly a bit of a workaround, but your problem almost certainly has nothing to do with your use of $$anonymous$$aterialPropertyBlock itself. I'd bet it has something to do with batching/instancing, which $$anonymous$$PB works with, while not using $$anonymous$$PB disables it.
Thank you, those are some good ideas to try out.