Godot: GLES2 2D Batching - Sprite order flickering.

Created on 4 May 2020  路  14Comments  路  Source: godotengine/godot

Godot version:
8426ed2650ac740796a1

OS/device including version:
Win10 64-bit GLES2

Issue description:
Very recently I've noticed flickering on certain Sprites that are inside of YSorted nodes. It's very difficult to reproduce in a minimal project.

Here is a GIF showing that a shadow may be appearing in front of node, and when bullets go traveling nearby, the shadows will draw where they should, then pop up again.

ezgif com-video-to-gif (2)

@lawnjelly Perhaps a batching edge case? These shadow Sprites are children of a node within a YSort, and these shadows are also set to be Behind Parent. The hierarchy is a few branches deep.

I haven't been working with this part of the project in a while, so I don't know exactly when it began, but builds from weeks ago exhibit no issue. In the meanwhile I will attempt to bisect.

Steps to reproduce:
N/A

Minimal reproduction project:
N/A

bug regression rendering

Most helpful comment

Not 100% sure here, but I got some minor flicker that happens when the camera reaches a certain position. I've modulated the scene of sprites red, tell me if you can observe it in this project.

Flickering.zip

image

All 14 comments

Perhaps a batching edge case?

It could be but think I'll need a minimum reproduction project for this, not knowing your project I don't know what is going wrong / what is expected. If you turn batching off and it doesn't happen, then it is a batching regression (apart from one bug in the legacy lighting that is fixed in the batching!).

Also if you can isolate this case and turn diagnose_frame on, the log might prove useful.

The flags slipped my mind. Yes, turning it off it goes away.

With some flickering and diagnose_frame enabled this is some of the information. Will keep trying to reproduce it minimally. It may require a lot of items, since the scenes in the game are pretty large collections of sprites.

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-1 [0] {0 0 0 0 }
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
        joined_item 2 refs
                (z -10)
                        batch D 0-0
                        batch R 0-2 [0] {255 230 251 213 } MULTI
        joined_item 1 refs
                (z -1)
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
        joined_item 3 refs
                (z -1)
                        batch D 0-0
                        batch R 0-3 [0] {255 255 255 128 } MULTI
        joined_item 11 refs
                        batch D 0-0
                        batch R 0-11 [0] {132 22 147 255 } MULTI
        joined_item 1 refs
                        batch D 0-1 c
        joined_item 1 refs
                        batch D 0-1 c
        joined_item 28 refs
                        batch D 0-0
                        batch R 0-18 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {132 22 147 255 } color
                        batch R 0-1 [1] {255 255 255 255 } color
                        batch R 0-1 [1] {132 22 147 255 } color
                        batch R 0-2 [1] {255 255 255 255 } MULTI color
                        batch R 0-4 [1] {214 103 230 255 } MULTI color
                        batch R 0-1 [1] {255 255 255 255 } color
        joined_item 1 refs
                        batch D 0-1 c
        joined_item 1 refs
                        batch D 0-1 c
        joined_item 1 refs
                        batch D 0-1 p
        joined_item 13 refs
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
canvas_end
        items reordered: 3
        light items joined: 2

canvas_begin FRAME 1
items
        joined_item 5 refs
                (z 40)
                        batch D 0-0
                        batch R 0-5 [0] {20 12 20 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 2 refs
                (z 40)
                        batch D 0-0
                        batch R 0-2 [0] {255 255 255 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 11 refs
                (z 40)
                        batch D 0-0
                        batch R 0-3 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-2 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-4 [0] {255 255 255 255 } MULTI
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 0 }
canvas_end

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-7 [0] {0 0 0 255 } MULTI
                        batch R 7-7 [1] {255 255 255 255 } MULTI color
canvas_end

canvas_begin FRAME 1
canvas_end

@lawnjelly Apologies on the delay with bisecting. Ran into issues with it last night, as it crossed over two bugs during the timeline. One with assertions not working, and the other with a recent std_vorbis.c crash. Lost a few hours to it today, had do some project modifications and awkward cherry picks.

But the problem first appears here 451c3fc0fb2feb0baaf8e32774c55ade66bd157f

Here is the diagnose frame for (BAD): 451c3fc0fb2feb0baaf8e32774c55ade66bd157f

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-1 [0] {0 0 0 0 }
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
        joined_item 2 refs
                (z -10)
                        batch D 0-0
                        batch R 0-2 [0] {255 230 251 213 } MULTI
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
        joined_item 17 refs
                        batch D 0-0
                        batch R 0-17 [0] {255 255 255 255 } MULTI
        joined_item 1 refs
                        batch D 0-1 p
        joined_item 13 refs
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
                        batch R 0-2 [1] {255 255 255 255 } MULTI
                        batch R 0-1 [2] {255 255 255 255 }
                        batch R 0-1 [0] {255 255 255 255 }
canvas_end
        items reordered: 3
        light items joined: 2

canvas_begin FRAME 1
items
        joined_item 5 refs
                (z 40)
                        batch D 0-0
                        batch R 0-5 [0] {20 12 20 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 2 refs
                (z 40)
                        batch D 0-0
                        batch R 0-2 [0] {255 255 255 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 11 refs
                (z 40)
                        batch D 0-0
                        batch R 0-3 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-2 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-4 [0] {255 255 255 255 } MULTI
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-1 [0] {255 255 255 0 }
canvas_end

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-7 [0] {0 0 0 255 } MULTI
                        batch R 7-7 [1] {255 255 255 255 } MULTI color
canvas_end

canvas_begin FRAME 1
items
canvas_end

canvas_begin FRAME 1
canvas_end

canvas_begin FRAME 1
canvas_end

Leaked object count: 1

And diagnose frame for (GOOD): 60609ff0ed357a38b58126791f7372c8aa3e446e

canvas_begin FRAME 1
items

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-1 r

canvas_begin FRAME 1
items
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 p
                        batch D 0-1 p
        joined_item 1 refs
                (z -10)
                        batch D 0-1 r
        joined_item 1 refs
                (z -10)
                        batch D 0-1 r
        joined_item 1 refs
                (z -10)
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 p
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r
        joined_item 1 refs
                        batch D 0-1 r

canvas_begin FRAME 1
items
        joined_item 5 refs
                (z 40)
                        batch D 0-0
                        batch R 0-5 [0] {20 12 20 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 2 refs
                (z 40)
                        batch D 0-0
                        batch R 0-2 [0] {255 255 255 255 } MULTI
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 1 refs
                (z 40)
                        batch D 0-1 p
        joined_item 11 refs
                (z 40)
                        batch D 0-0
                        batch R 0-3 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-2 [0] {255 255 255 255 } MULTI
                        batch R 0-1 [1] {32 32 32 255 } color
                        batch R 1-1 [2] {255 255 255 255 } color
                        batch R 0-4 [0] {255 255 255 255 } MULTI

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-1 r

canvas_begin FRAME 1
items

canvas_begin FRAME 1
items
        joined_item 1 refs
                        batch D 0-0
                        batch R 0-7 [0] {0 0 0 255 } MULTI
                        batch R 7-7 [1] {255 255 255 255 } MULTI color

canvas_begin FRAME 1
items

I also have a similar issue on my real project but can't make a smallest reproducible project at the moment.

I wouldn't be surprised if there were a couple of bugs to fix in these, but it was worth getting them in while we are still in beta as it will improve things significantly for people using lights. We can work it which is causing the problem by using the project settings:

  • If you set item_reordering_lookahead to 0 it will turn off item reordering
  • If you set light_max_join_items to 0 it will turn off light item joining

If both of these are off and it still happens it is likely the light modulate fix.

Edit - Had a look at the logs. it is managing to do a load more joining in the (bad) log! Which is very good (apart from the visual regression obviously lol) :grin:

Gave some values a test.

item_reordering_lookahead = 0 (No flickering)
item_reordering_lookahead = 1 (No noticeable flickering, unsure if it may manifest rarely.)
item_reordering_lookahead = 2 (Obvious flickering)

light_max_join_items = 0 (Flickering)

Both at 0, no flickering. Though not sure if the second option affects it at all.

Ah that's kind of good news. Reordering should be easier to fix, I'll see if I can work out what might be going wrong. Any test projects welcome! :+1:

No luck yet, have tried dozens of things that randomly pop in my head for the past two days. Trying to recreate things from the scene structure of the main project, but it eludes me.

ezgif com-video-to-gif (3)

Item reordering occurs at the moment when there are items (only single rects) that are the same texture that are separated by another item that does not overlap. In these conditions it should be able to move the item to better enable joining, without changing the rendered result. As such you'll only get reordering when you have a mix of different e.g. sprites interleaved with each other. So your field of blue Godot faces won't be expected to reorder.

There may be exceptions though where it should not be done, at the moment it is turned off when it crosses to a different z_index, there may be another case I'm missing. I'll have a look over the code and see if I've missed something obvious.

Oh, thanks. I'll try random textures in between things in the meanwhile.

Not 100% sure here, but I got some minor flicker that happens when the camera reaches a certain position. I've modulated the scene of sprites red, tell me if you can observe it in this project.

Flickering.zip

image

Fantastic, I'll try that project! :+1: That will save me loads of time.
Yes - can reproduce! Thanks!
Setting the item_reordering_lookahead to 0 does seem to prevent it, and setting it to 32 seems to slightly increase it. Until I sort this, feel free to just set it to 0, as this is an 'icing on the top' kind of optimization.

Got it, it's a simple logic error in the overlap tests. It is only considering the overlap tests for the moving item, and not the item it replaces (which may wrongly jump over another item).

i.e. With
A B C D
swapping D with B. It may be okay to move D to B, but that doesn't mean it is ok to move B to D, as it may be wrongly moving after C.

I'll get this fixed. :+1:

Fixed by #38503.

Was this page helpful?
0 / 5 - 0 ratings