• Unity
  • Black lines

Related Discussions
...

Hey there!

We recently started using Spine for our animations and came across an issue.There seems to be more people with this issue, judging by your search system, but none of the fixes there fixed it for us. Hence the new post.

As you can see, our animation here has these weird small black lines between the different sprites.
We tried setting the Premultiply alpha and the bleed inside the texture packer settings in the Spine exporter, but nothing seems to help.
I also tried fiddling with the Unity sprite settings (mipmaps, filters) but still nothing.

Any suggestions are highly welcome!

Check premultiply alpha parameter in pack settings.Select spine object in Unity Hierarchy window, then in inspector expand Advanced tab and disable (PMA Vertex Colors) check box.

Thank you for the reply!

Sadly, this didn't fix the issue. I do however see an error in that component:

We do use Linear colour space though since all of our shaders are made for that.

Enabling the "Straight alpha texture" in the material seems to make the black lines worse.

Thanks again @mfedorov for answering!

Are you sure that all three parts are correctly set up: texture export with Premultiply alpha disabled, and Texture and Material settings as described here? You may also want to open Edit - Preferences - Spine in Unity and set the Atlas Texture Reference Settings to the StraightAlphaPreset, so all your newly imported assets are set up automatically for Straight alpha workflow. This preset option has recently been added for convenience.

Thank you, that link was very helpful!

Interestingly, this fixed the problem in the prefab, but not during runtime.

Glad it helped!

bladynator ha scritto

Interestingly, this fixed the problem in the prefab, but not during runtime.

This sounds like a problem with re-serialization / saving assets. You could perform a quick test if the problem persists when you drag the Skeleton into the scene again and enter play mode as before (if by during runtime you meant in Editor play mode), or creating another prefab and testing it again to see if perhaps the prefab has not been updated correctly or some outdated state remains saved.

So, I tried to change a bunch of stuff and found something that got rid of the black lines.

You see, I use a CustomMaterialOverride with my own custom shader. Disabling this override gets rid of those black lines. I'll experiment a bit further about what in that shader causes it, but maybe you already have an idea?

This is the code I use for the override incase it helps:

Material[] allMats = mesh.materials;
        skel.CustomMaterialOverride.Clear();

    foreach (Material mat in allMats)
    {
        Texture sprite = mat.mainTexture;
        skel.CustomMaterialOverride.Add(mat, WaveController.Instance.enemyMat);
        mat.shader = WaveController.Instance.enemyShader;
        mat.CopyPropertiesFromMaterial(WaveController.Instance.enemyMat);
        mat.mainTexture = sprite;
    }

So far, it seems to work for other animations I made with Spine2D, so that's still a bit odd.

Just a silly question, but did you check that WaveController.Instance.enemyMat is using the correct setup?

What you could also do is filter the Project panel by "t:material" and have a quick review if any are setup incorrectly.

Sorry, i'm not quite sure I understand your question.
This is a custom shader, so i'm not sure if it uses your prefered setup. How can I check this?
I disabled every effect in that shader, but it still gives me the same result.
I tried adding the "#pragma shader_feature" to my shader, but that didn't do much either.

Since you are copying the setup of WaveController.Instance.enemyMat, my question was whether this material enemyMat is set up correctly.
From your answer I think you understood it correctly.

What kind of custom shader are you using here? Are you copying between materials using the same shader? So is every material in Material[] allMats = mesh.materials; using the same shader as WaveController.Instance.enemyMat?

bladynator ha scritto

I disabled every effect in that shader

What kind of effects did you disable?

bladynator ha scritto

I tried adding the "#pragma shader_feature" to my shader, but that didn't do much either.

What #pragma shader_feature did you add? Just adding this statement will not do anything, if the respective #if DEFINITION shader branches do not exist in the shader.

In case you are using a shader which uses premultiplied alpha in a non-configurable fashion, you would need to change the respective lines of code that perform the multiplication with the texture's alpha value, like texture.rgb *= texture.a; or similar.

Ah, alright! I'm really not that good with shaders, so i'm just trying stuff 🙂

Yes, you understood that correctly. I override every shader in every material that Spine2D makes. (which is currently just 1 material with 1 shader, so the foreach only loops once).
The shader I currently use has a bunch of effects that you can enable to add them to each other, but I get the same black lines with all of those effects disabled.
The frag shader that remains is this:

fixed4 frag (v2f i) : SV_Target
{
      fixed2 uvRect = i.uv;
      fixed4 col = tex2D(_MainTex, i.uv) * i.color * _Color;
      col.rgb *= col.a;

  col.a *= _Alpha;
}

Removing that last line (col.a *= _Alpha) doesn't change much, and adding your suggested line after it doesn't do much either.
Multiplying the col.rbg by 2 makes the sprite lighter, so at least I know the shader is still doing SOMETHING 😉

bladynator ha scritto

Removing that last line (col.a *= _Alpha) doesn't change much,

That's why I wrote

like texture.rgb *= texture.a; or similar.

You were one line of code off with your modification, the line above should have been removed.
Every pre-multiplication of the base color (color.rgb) by an alpha value has to be removed when you want to turn pre-multiplied alpha into normal straight alpha.

BTW: your shader is incorrect anyway, as it performs col.a *= _Alpha after the alpha pre-multiplication statement instead of before.

bladynator ha scritto

and adding your suggested line after it doesn't do much either.

I did not suggest to add any line after existing code. If you meant the #if DEFINITION section, then this needs to be wrapped around the code, not added afterwards.

bladynator ha scritto

Yes, you understood that correctly. I override every shader in every material that Spine2D makes. (which is currently just 1 material with 1 shader, so the foreach only loops once).

The main question was:

Are you copying between materials using the same shader?

But I guess you are. If you were copying properties between a Material with a Spine shader and a custom non-Spine shader, then things will only work by chance.

In general, please always tell us up-front when you are not using Spine shaders but custom ones.

Again, i'm not that good with shaders yet 🙂 And it seems like I misunderstood some of your questions..

First of all: YES, it is fixed by removing the col.rgb *= col.a;

The shader is correct, but the _Alpha variable is used for some other special effects that I didn't include in my shipit, so it was a bit redundant.

As for the overrides, I have 2 materials: one that Spine made for me with the Spine shader (mat.shader) and another different material with my own shader (WaveController.Instance.enemyShader)

Thank you so much for your time, help and extra information! I really appreciate it!

Glad it's working now!

bladynator ha scritto

The shader is correct, but the _Alpha variable is used for some other special effects that I didn't include in my shipit, so it was a bit redundant.

What I wanted to say is that the col.a *= _Alpha; statement has no effect in your shader. If you don't need it: good, but then delete it. Otherwise you will later be wondering why setting the _Alpha value has no effect.

5 anni dopo

In case anyone is still searching the same issue, I have just show Erika showed how she fixed it here: