Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-235953

Entity eyes render type doesn't blend non-black transparent pixels properly

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • 24w39a
    • 1.17.1, 1.19.3, 1.19.4 Pre-release 2, 1.19.4, 23w12a, 23w13a, 23w14a, 23w16a, 23w17a, 23w18a, 1.20 Pre-release 1, 1.20 Pre-release 4, 1.20.1, 23w31a, 1.20.4, 24w07a, 1.21
    • GNU/Linux 5.10.0-8-amd64 #1 SMP Debian 5.10.46-4
      Java 17-ea+35-Debian-1
    • Confirmed
    • Rendering

      Effects and context

       
      The blending works fine as long as transparent pixels in the source texture (the eye layer texture) are pure black (#00 00 00). However, if transparent pixels are not black, the body and eye layer textures are blended incorrectly, as if the eye layer texture didn't have transparent pixels at all. A screenshot that shows the results is attached, with a eye layer PNG texture that reproduces this issue by virtue of not having black transparent pixels. A resource pack that exhibits the problem is also attached.
       
      I'd like to highlight that non-black transparent pixels are a normal condition in well-formed PNG files, which can be generated by an encoder that does not care or wants to clear the color values of transparent pixels, or an artist that purposefully desires to leave a hidden message. Therefore, under most circumstances, a correct program should not end up rendering transparent pixels as non-transparent, no matter what their color values are.

      Analysis and possible fix

      The assets/minecraft/shaders/core/rendertype_eyes.json render program file, which is used to define the shader stages responsible for rendering the entity eye layers for Endermen, the Ender Dragon, Phantoms and spiders, reads as follows in its first lines:

      "blend": {
          "func": "add",
          "srcrgb": "srcalpha",
          "dstrgb": "1-srcalpha"
      },

      In addition, Minecraft code assigns a ADDITIVE_TRANSPARENCY render state shard, which initializes glBlendFunc with both blending factor parameters set to GL_ONE, while creating the entity eyes render type, in the field EYES, at the net.minecraft.client.renderer.RenderType class. By itself, this blending mode would just sum the colors and alpha values of both blended textures, which would look wrong in all cases. To try to counter this fact, rendertype_eyes.json declares that the source color blending factor is the alpha of the source texture. But this fails to take into account the blending factor for the alpha channel, which was fixed to 1 by the render state shard. Therefore, the end result is that colors from the blended textures are just added together without any regard for the alpha channels at all, which is likely not intended given the render program declaration, and causes the issue described in this report.
       
      A fix that would not require any Java code change at all would be modifying the first lines of rendertype_eyes.json so they read as follows:

      "blend": {
          "func": "add",
          "srcrgb": "srcalpha",
          "dstrgb": "1-srcalpha",
          "srcalpha": "srcalpha",
          "dstalpha": "1-srcalpha"
      },

      This fix was tested by me to work on a resource pack affected by this issue, without any noticeable performance impact.

      Disclaimer

      Even though the attached screenshot shows that I'm using the Sodium mod, this issue also happens in vanilla 1.17.1, without any mod loaded. It's not caused by modding the game.

            Unassigned Unassigned
            AlexBlocks123 Alejandro González
            Votes:
            8 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: