Layers Bugged?

I was playing about with layers yesterday, I was getting some extremely odd results, to the point that my nut was so well and truly mangled I decided never to touch them again, and went back to simple ordered drawing.

I have a sprite of a car body, just the body. Then I have other sprites for the lights, I draw the lights in the same position as the body sprite, so I can turn on indicators, front, brake, reversing lights without having to create a graphic for every single combination. This approach was the only one that made any sense to me.

Now, the drawing routine was setup to to draw Front to Back, so layer 0.0 would be the back, and 1.0 would be foremost. I built up the scene as you would expect, background, car, hedges, bridges, trees etc, all in the logical order. This was fine, however, when I turned on any lights of the car the color of my car body changed, not dramatically, but it got lighter. I tried putting the lights on a different layer, so the car was on 0.2 and the lights were on 0.3, still the same. My car body also changed colour at certain points in the world without any reason, but in repeatable places. During testing I tried setting up a trigger location, so when the car was within certain screen positions a different sprite would be drawn, the car body changed color. This wasn’t on the same layer!

The reason for wanting layers was so I could change the car layer so it could run over and under certain parts of the 2d world. This is where the next strange behaviour was noticed. If I moved the car from 0.2/0.3 to 0.5/0.6 items on layer 0.1 started drawing in a different order. I honestly thought I was going bonkers. I tried all sorts of different combinations but no matter what I tried I couldn’t get around the car body changing color when the lights were turned on. I’m sure you’d be quite alarmed if every time you put your foot on your brake pedal your car changed color, or when you turned on indicators the whole care flashed! This wasn’t an acceptable situation.

So, layers. What’s going on?

Without any sample code or assets, it’s very difficult to say what might be happening here. I’m going to guess that the texture containing the lights might not have zero alpha all the way across the areas where it should be totally transparent. But without seeing the assets or the code, it’s hard to tell for sure.

No, all images are completely blank where they should, if they weren’t I’d have similar problems on the single layer.

Still can’t help without seeing any of the assets and code.






This is the car body, glass and the lights. The headlights and reversing lights are difficult to see as their working pixels are white.) I’ve checked and checked and can’t see anything wrong with either. I’ve even built a color map of the sprites when they’re created and checked pixel by pixel for any alpha problem.

I tried to update an MP4 showing the problem but it won’t allow me to.

I really can’t get my head around why showing a sprite on one layer should affect another. I have changed code since my first post and as a test earlier I moved the hazzards to layer 0.7 just to see what would happen. I still have the problem with the car body and glass changing color, and the objects on layer 0.4 draw in a different order, the hedges end up on top of the trees when the hazzards are drawn. What on earth could cause this?

Draw Code:
` GraphicsDevice.Clear(Color.Black)
SB.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.LinearClamp, Nothing, Nothing, Nothing, Cam.TranslationMatrix)

    '//  BACKGROUND
    SB.Draw(BackgroundRender, New Rectangle(0, 0, WorldWidth, WorldHeight), Nothing, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0)


    ''//  BRIDGES is car is on top
    If Car.CarOnTop = True Then
        Car.DrawLayer = 0.3
    Else
        Car.DrawLayer = 0.1
    End If

    '//  CAR
    SB.Draw(ShadowTexture, New Vector2(Car.Position.X + 4, Car.Position.Y + 4), Nothing, New Color(0, 0, 0, 100), Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    SB.Draw(Car.Texture, Car.Position, Nothing, New Color(100, 100, 200, 255), Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    SB.Draw(CarGlassTexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)

    If Car.LightsOn = True Then
        SB.Draw(HeadLightsTexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    End If

    If Car.BrakesOn = True Then
        SB.Draw(BrakelightsTexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    End If

    If Car.Reversing = True Then
        SB.Draw(ReverseLightTexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    End If

    If (Car.LeftIndOn Or Car.Hazzards) And Car.IndRelay Then
        SB.Draw(LeftITexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    End If

    If (Car.RightIndOn Or Car.Hazzards) And Car.IndRelay Then
        SB.Draw(RightITexture, Car.Position, Nothing, Color.White, Car.Rotation + Rotate, Car.Centre, Car.Scale, SpriteEffects.None, Car.DrawLayer)
    End If

    SB.Draw(BridgeRender, Vector2.Zero, Nothing, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0.2)


    '//  HEDGE AND TREES
    SB.Draw(TreesTexture, Vector2.Zero, Nothing, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0.4)
    SB.Draw(HedgeTexture, Vector2.Zero, Nothing, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0.4)

    '//  BOOM after collision
    If Boom.Visible = True Then
        SB.Draw(BoomTexture, Car.Position, Nothing, New Color(Boom.ColorValue, Boom.ColorValue, Boom.ColorValue, Boom.ColorValue), Boom.Rotation, Boom.Centre, Car.Scale, SpriteEffects.None, 0.4)
    End If

    SB.End()`

No idea why the SB.Begin is outside the code block or why a chunk of the code is red!!

Or the hedges and trees for that matter.

What happens when you draw many sprites at the same depth with the SpriteSortMode.FrontToBack (or BackToFront) ?
They may be randomly drawn ? (i think about your car layer. In SQL for ex, if you try to sort many items which have the same key, they are ramdomly sorted)

What if you try setting each sprite a decreasing depth ? (like depth -= 0.01; for each layer) just to see what happens when you change to BackToFront.
Do you sprite use PremultitpliedAlpha ?

Hi Alkher. Thanks for the suggestions, putting each and every graphic on it’s own distinct layer does fix the problem, no more changing colors. Yay!

I’m not familiar with PremultitpliedAlpha, where is this/these settings?

I like your SQL metaphor, I’m very used to the foibles of many SQL engines. However, if there had been a randomness to the textures swapping position, perversely it probably would have led me to your suggestion.

There are 2 things here though that I think need some explanation:

  1. How/why are colors changing when sprites are drawn on the same layer.
  2. How/why do textures change position in a layered system but don’t when deferred.

How could I pass these questions to a Dev? I’ve not seen any other posts on this subject and I can’t believe I’m the only person playing about with layers. I’m only messing about and learning at the moment but if something ‘wrong’ is happening it’s always nice to know why.

Concerning the PremultitpliedAlpha:
Explanation from NVidia: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

And from Shawn Hargreaves:
https://blogs.msdn.microsoft.com/shawnhar/2009/11/06/premultiplied-alpha/
https://blogs.msdn.microsoft.com/shawnhar/2010/04/09/how-shawn-learned-to-stop-worrying-and-love-premultiplied-alpha/
https://blogs.msdn.microsoft.com/shawnhar/2010/04/08/premultiplied-alpha-in-xna-game-studio-4-0/ (where is the parameter in the contentprocessor)

Concerning the colors changes, maybe they are multiplied, or added, or anything else. A look into the SpriteBatch / Monogame 's sourcecode may answer this.

You can create an issue on GitHub if you think it is relevant :wink: