Layer rendering order group by entity rather than by layer?

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Layer rendering order group by entity rather than by layer?

Post by kirazy »

This may be difficult to convey, but:

Take an entity, e.g. my modded assembling machine:
Image

This has four layers, Base, Mask, Highlight, Animation

In making my mod most of the structures on the screen are rendered with multiple layers, and I've noticed some things.



If two entities have layers, the layers appear to be drawn interleaved, rather than all on top or all on bottom with respect to render order.

Is this a modding request? A bug? Something I just get to deal with? D:

I've also seen it when dealing with pipe_pictures on assembling machines, where the mask of the assembling machine will cover the pipe picture, either partially or entirely (bob-mods shown, it doesn't happen on mine because only the base layer would obstruct and the rest are transparent/nearly invisible):
Image
User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2529
Joined: Fri Nov 06, 2015 7:41 pm

Re: Layer rendering order group by entity rather than by layer?

Post by Deadlock989 »

I'm not quite sure what you mean with the "interleaved" thing, I haven't come across anything like this. If you mean roboports specifically, there are some hoops to jump through there with the split door animation and the mask/patch that hides the bot's descent.

Pipes are a menace in general. With pipe covers and pipe pictures, there is the secondary_draw_order property in the fluid box definitions, which can be used to finesse how they are rendered relative to the main entity.
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

Deadlock989 wrote: Thu Mar 19, 2020 1:21 am I'm not quite sure what you mean with the "interleaved" thing, I haven't come across anything like this. If you mean roboports specifically, there are some hoops to jump through there with the split door animation and the mask/patch that hides the bot's descent.
I have all these, I replicated the vanilla structure/graphics setup.

If you look closely at the animation I included, it's not the whole entity that's visible, it's strictly the highlights layer. Not the base layer, not the mask layer, just the highlights layer, so the last layer in the stack:

Image

Edit: I'm not really sure what's happening here, actually.

Both the base_patch definition and the construction robot have three layers, but the issue is only with the last layer.
Last edited by kirazy on Thu Mar 19, 2020 1:30 am, edited 1 time in total.
User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2529
Joined: Fri Nov 06, 2015 7:41 pm

Re: Layer rendering order group by entity rather than by layer?

Post by Deadlock989 »

kirazy wrote: Thu Mar 19, 2020 1:24 am If you look closely at the animation I included, it's not the whole entity that's visible, it's strictly the highlights layer. Not the base layer, not the mask layer, just the highlights layer, so the last layer in the stack. :X
So the bots have layers, and the roboport has layers ... Yeah, that might be causing issues. The way that the roboport "patch" draw order is hardcoded might be assuming that bots are all one layer. The patch is "higher" than the main body of the roboport but your bot has enough layers such that the highest ones are even higher than that. That would be an interface request - total control over layer order for all layers of all entities :p
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

Deadlock989 wrote: Thu Mar 19, 2020 1:30 amThat would be an interface request - total control over layer order for all layers of all entities :p
I don't necessarily want control, just for all the layers in an entity to be rendered at the same layer in a block, rather than this weird way they're being interleaved.
User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2529
Joined: Fri Nov 06, 2015 7:41 pm

Re: Layer rendering order group by entity rather than by layer?

Post by Deadlock989 »

kirazy wrote: Thu Mar 19, 2020 1:31 am I don't necessarily want control, just for all the layers in an entity to be rendered at the same layer in a block, rather than this weird way they're being interleaved.
I doubt that's possible. Layers have to have a kind of "Z order" or you get "Z-fighting" (my terms, not the devs') - this has happened before, been reported as a bug, fixed.

Roboports probably assume the following, bottom to top:

- Roboport shadow
- Roboport body
- Roboport upper door
- Bots
- Roboport lower door
- Roboport patch

So if your bot has three layers, the top layer will be higher than the roboport patch. So you need, at a minimum, some equivalent of secondary_draw_order for specific bits of the roboport structure definition.
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

Deadlock989 wrote: Thu Mar 19, 2020 1:37 am
kirazy wrote: Thu Mar 19, 2020 1:31 am I don't necessarily want control, just for all the layers in an entity to be rendered at the same layer in a block, rather than this weird way they're being interleaved.
I doubt that's possible. Layers have to have a kind of Z order or you get "Z-fighting" - this has happened before, been reported as a bug, fixed.

Roboports probably assume the following, bottom to top:

- Roboport shadow
- Roboport body
- Roboport upper door
- Bots
- Roboport lower door
- Roboport patch

So if your bot has three layers, the top layer will be higher than the roboport patch. So you need, at a minimum, some equivalent of secondary_draw_order for specific bits of the roboport structure definition.
I don't mean the same z order, rather:

- Roboport base_patch
-- Layer 3
-- Layer 2
-- Layer 1
- Construction Robot
-- Layer 3
-- Layer 2
-- Layer 1

And not:

- Construction Robot Layer 3
- Roboport base_patch Layer 3
- Roboport base_patch Layer 2
- Roboport base_patch Layer 1
- Construction Robot Layer 2
- Construction Robot Layer 1
User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2529
Joined: Fri Nov 06, 2015 7:41 pm

Re: Layer rendering order group by entity rather than by layer?

Post by Deadlock989 »

But all of the bot has to be lower than the roboport patch. That's what the patch is for ... to hide the bot. If the bot is a "block" that is always higher than the roboport "block" then none of that would work.

I'm pretty sure that's why layer control isn't just handed out in general. Messing with it has a domino effect. You can get a taste of that when you have elaborate pipe covers and give them a high secondary draw order and then they end up being rendered on top of things further "south" that they are supposed to be "behind". It's a 2D game pretending not to be one, remember.

Still, won't hurt to ask, see what posila says.
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

Deadlock989 wrote: Thu Mar 19, 2020 1:42 am But all of the bot has to be lower than the roboport patch. That's what the patch is for ... to hide the bot. If the bot is a "block" that is always higher than the roboport "block" then none of that would work.

I'm pretty sure that's why layer control isn't just handed out in general. Messing with it has a domino effect. You can get a taste of that when you have elaborate pipe covers and give them a high secondary draw order and then they end up being rendered on top of things further "south" that they are supposed to be "behind". It's a 2D game pretending not to be one, remember.

Still, won't hurt to ask, see what posila says.
Oh, I follow.

I was thinking of treating base_patch as a whole block, not the entire Roboport.

Edit: I think it's the rendered assuming entities/special parts of entities have finite numbers of layers and only grabbing those, rather than grabbing all the layers. :<

Idk.

Edit 2: Tbh:


The highlights layers are like, stacking, since they're blend_mode = "additive", I guess. I'm confused...
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

My solution to this for now is just to add an empty pixel as a padding layer at the bottom of the stack.

Works flawlessly. 8D...
posila
Factorio Staff
Factorio Staff
Posts: 5444
Joined: Thu Jun 11, 2015 1:35 pm
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by posila »

kirazy wrote: Thu Mar 19, 2020 2:41 am My solution to this for now is just to add an empty pixel as a padding layer at the bottom of the stack.

Works flawlessly. 8D...
That could not possibly fix the stacking highlights, could it?

Rendering of the game works as follows, when update finishes, "max render threads" number of threads are fired up, and do render preparation for some range of tile rows visible on screen. Render preparation is iterating through entities and calling draw on them (plus on decoratives and smokes and particles). Draw function of an entity knows how to draw the entity, and it adds for each layer entity needs to be drawn structure we call SpriteDrawOrder (order as in command) into something we call DrawQueue (this is why more layers uses more CPU power - it has more SpriteDrawOrders to create and send to GPU).

After a thread is finished collecting all sprite draw orders for its row of tiles, it sorts some of the render layers by their position and secondary draw order (in this case order doesn't mean "command" ... naming things, am I right?). Secondary draw order is used when entity is composed from multiple elements that need to be drawn in the same render layer - including when sprite with layers is drawn (each layer adds one to the previous secondary draw order).

When robot is ascending or descending to roboport it is drawn on position of the roboport (with extra shift to animate the ascend/descend - but map position that is used for sorting is same as roboport's), so that secondary draw order to make it sort in-between elements of the roboport. And problem is that the person who made this didn't leave any gaps in secondary draw orders for extra sprite layers.

Anyhow, I'll probably fix this by just multiplying secondary draw orders used by roboport and robot rendering by 5 or 10. But in 0.18 we have optimized sprite sorting and the new sorting method is stable, so we should not need to increment secondary draw order for sprite layers anymore, but at the moment, I am not brave enough to make such a change.
User avatar
kirazy
Filter Inserter
Filter Inserter
Posts: 430
Joined: Tue Mar 06, 2018 12:18 am
Contact:

Re: Layer rendering order group by entity rather than by layer?

Post by kirazy »

posila wrote: Thu Mar 19, 2020 8:32 amThat could not possibly fix the stacking highlights, could it?
Correct, but it fixes the robot showing through the roboport, which of the two issues looks way more odd.
Post Reply

Return to “Modding interface requests”