[posila] [1.1.32] Multilayer tree leaf sprites do not use blending modes correctly

Post Reply
User avatar
Reika
Filter Inserter
Filter Inserter
Posts: 579
Joined: Tue May 19, 2015 1:56 am
Contact:

[posila] [1.1.32] Multilayer tree leaf sprites do not use blending modes correctly

Post by Reika »

The title is somewhat vague because I am not sure exactly where the error is, in rendering, in prototype parsing, or elsewhere.

Basically, I have trees which are intended to be surrounded by a glowing halo, and I am trying to use the new glow drawing system to enable that. Part of this requires layering in an additive-blended texture around the leaves, to create a base halo, resulting in a prototype whose "leaves" entry in each variation looks like this:

Code: Select all

leaves = {
    layers = {
      {
        filename = "__base__/graphics/entity/tree/02/tree-02-a-leaves.png",
        flags = {
          "mipmap"
        },
        frame_count = 3,
        height = 154,
        hr_version = {
          filename = "__base__/graphics/entity/tree/02/hr-tree-02-a-leaves.png",
          flags = {
            "mipmap"
          },
          frame_count = 3,
          height = 310,
          scale = 0.5,
          shift = {
            0,
            -2.3125
          },
          width = 184
        },
        shift = {
          -0.0625,
          -2.3125
        },
        width = 96
      },
      {
        blend_mode = "additive",
        filename = "__Bioluminescence__/graphics/entity/tree/tree-02-a-leaves.png",
        flags = {
          "light"
        },
        frame_count = 3,
        height = 154,
        hr_version = {
          blend_mode = "additive",
          filename = "__Bioluminescence__/graphics/entity/tree/hr-tree-02-a-leaves.png",
          flags = {
            "light"
          },
          frame_count = 3,
          height = 310,
          scale = 0.5,
          shift = {
            0,
            -2.3125
          },
          width = 184
        },
        shift = {
          -0.0625,
          -2.3125
        },
        width = 96
      }
    }
  },
However, ingame, the result is very much not additive:
Image

I was of course expecting something more like this:
Image

Me and Honktown spent the better part of an hour digging through this on discord last night, and neither of us has any idea what is going on. One thing that does stand out, however, is that the prototype inspector lists those additional layers as using normal blending:
Image

This is despite a log of the prototype at time of registration very clearly listing the blend mode as additive (see code above), and with no other mods in the prototype history. This implies that whatever internal code parses the lua table into the game objects is failing to read the blend mode, or forcibly overriding it.
Image

posila
Factorio Staff
Factorio Staff
Posts: 4991
Joined: Thu Jun 11, 2015 1:35 pm
Contact:

Re: [1.1.32] Multilayer tree leaf sprites do not use blending modes correctly

Post by posila »

Blend modes are essentially respected only for basic sprite drawing. Anything that uses some kind of effect (like trees), or has it's own special drawing pipeline (lights, tiles, ...), has specific blend mode

Additive blending mode gets turned into default blending mode (premultiplied alpha blending) with tint alpha set to 0 (why this works is described in FFF #172: https://www.factorio.com/blog/post/fff-172) so that we can combine default blending and additive blending without creating breaks in draw batches.

This doesn't work for trees, because their effect uses alpha channel of tint for desaturation level, instead of alpha.

Lastly, there is some precalculations going on with leaves sprite and normal map sprite, to make sure their texture coordinates will be aligned if the sprites have different dimensions, and that happens only for the first layer ... so it is kind of incorrect to even draw the sencond layer with the tree effect.

Sooo ... I am thinking what to do about this.
1) Make layers use basic sprite drawing instead of tree effect (which will create breaks in draw batches)
2) Pack desaturation level into the vertex data differently, so the alpha can still be used (this would fix additive blending mode)
3) Initialize pipeline state object for the effect for all possible blending modes like we do for basic sprite drawing pipeline states
4) Leave things as is

User avatar
Reika
Filter Inserter
Filter Inserter
Posts: 579
Joined: Tue May 19, 2015 1:56 am
Contact:

Re: [1.1.32] Multilayer tree leaf sprites do not use blending modes correctly

Post by Reika »

posila wrote:
Mon May 03, 2021 10:21 am
Blend modes are essentially respected only for basic sprite drawing. Anything that uses some kind of effect (like trees), or has it's own special drawing pipeline (lights, tiles, ...), has specific blend mode

Additive blending mode gets turned into default blending mode (premultiplied alpha blending) with tint alpha set to 0 (why this works is described in FFF #172: https://www.factorio.com/blog/post/fff-172) so that we can combine default blending and additive blending without creating breaks in draw batches.

This doesn't work for trees, because their effect uses alpha channel of tint for desaturation level, instead of alpha.

Lastly, there is some precalculations going on with leaves sprite and normal map sprite, to make sure their texture coordinates will be aligned if the sprites have different dimensions, and that happens only for the first layer ... so it is kind of incorrect to even draw the sencond layer with the tree effect.

Sooo ... I am thinking what to do about this.
1) Make layers use basic sprite drawing instead of tree effect (which will create breaks in draw batches)
2) Pack desaturation level into the vertex data differently, so the alpha can still be used (this would fix additive blending mode)
3) Initialize pipeline state object for the effect for all possible blending modes like we do for basic sprite drawing pipeline states
4) Leave things as is
Without really knowing a whole lot about your rendering backend, 3 seems the best choice, as it is something you already know how to do and have a framework for.

#2 could also be good, if it is not a ton of work.
Image

Post Reply

Return to “Assigned”