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

Mipmaps are too dark around transparent edges in texture (e.g. side of grass)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.13, Minecraft 1.13.1-pre1, Minecraft 1.14.2, Minecraft 1.14.3 Pre-Release 2, Minecraft 1.14.3, Minecraft 1.14.4 Pre-Release 6, 1.14.4, 1.15 Pre-release 1, 1.15.2, 1.16.1, 1.16.5, 21w10a, 1.17, 1.17.1, 21w37a, 21w38a, 21w42a, 21w43a, 1.18 Pre-release 1, 1.18 Pre-release 7, 1.18 Pre-release 8, 1.18 Release Candidate 3, 1.18, 1.18.1 Release Candidate 1, 1.18.1, 22w03a, 22w05a, 1.18.2, 22w13a, 22w15a, 22w18a, 22w19a, 1.19 Pre-release 1, 1.19 Pre-release 2, 1.19 Pre-release 3, 1.19 Pre-release 4, 1.19, 1.19.1 Pre-release 5, 1.19.1, 1.19.2, 22w44a, 22w46a, 1.19.3 Pre-release 1, 1.19.3 Pre-release 2, 1.19.3, 23w03a, 23w04a, 23w05a, 1.19.4 Pre-release 1, 1.19.4, 23w12a, 23w13a, 1.20.1, 23w33a, 24w13a, 24w14a
    • None
    • Confirmed
    • Rendering
    • Normal
    • Platform

      The bug

      This has been an issue for a while. It's especially noticeable at level 3 of the side of grass. See the screenshots, where I placed a row of grass on a row of dirt. With mipmaps, half of the grass block is practically black at the 'optimal' distance where the 2x2 mipmap or further is used.

      How to reproduce

      Open this world World.zip with these settings options.txt and look straight ahead without moving.
      Observe the dark patches with the side of the grass.

      Proposed solution

      Using Yarn mappings for 1.14.4, replace this method:

      net.minecraft.client.texture.Sprite
          private static int blendPixels(int int_1, int int_2, int int_3, int int_4) {
              return SRGBAverager.average(int_1, int_2, int_3, int_4);
          }
      

      using these classes provided by jonathan2520: SRGBAverager.java SRGBCalculator.java SRGBTable.java

      Original analysis

      I've looked it up in MCP 9.30/9.31 (corresponding to Minecraft 1.10.2). In net.minecraft.client.renderer.texture.TextureUtil, generateMipmapData is responsible for mipmap generation. It turns out not to use proper weighting by the alpha channel. Anything that isn't fully transparent is given the full weight, and anything that is is treated as black. That's where the darkness comes from.

      The correct model is most natural when using colors premultiplied by alpha: just average everything. If you don't use premultiplied colors, you must multiply colors by alpha before averaging and divide the resulting color by the resulting alpha afterward.

      Premultiplied also has the advantage that any blending steps you don't control directly work correctly, like texture filtering and frame buffer blending. Minecraft won't really experience either the advantages or the disadvantages, but it's the cleaner model that would've prevented problems like this bug from the start. That's something to consider.

      Adding to the problem is that Minecraft tries to apply gamma correction to the alpha channel. That blows up the opacity, only emphasizing exactly those texels that are too dark. Gamma correction of the alpha channel doesn't make sense anyway because colors can deviate either way depending on what's blended with what. The general standard—which is also what you'll get natively if you enable frame buffer and texture sRGB—is to use sRGB (which is a little more involved than x^2.2) for colors and keep the alpha channel linear.

        1. 1.14.3 mipmap levels=4.png
          1.14.3 mipmap levels=4.png
          1.38 MB
        2. 2021-10-21_00.28.24.png
          2021-10-21_00.28.24.png
          1.32 MB
        3. 2021-11-11_13.24.08.png
          2021-11-11_13.24.08.png
          91 kB
        4. grass_block_side_overlay.png
          grass_block_side_overlay.png
          0.3 kB
        5. Grass1BigView.png
          Grass1BigView.png
          692 kB
        6. Max level 0.png
          Max level 0.png
          87 kB
        7. Max level 4.png
          Max level 4.png
          87 kB
        8. options.txt
          3 kB
        9. Original 1.11.2.png
          Original 1.11.2.png
          88 kB
        10. Proof of concept.png
          Proof of concept.png
          89 kB
        11. SRGBAverager.java
          3 kB
        12. SRGBCalculator.java
          2 kB
        13. SRGBTable.java
          2 kB
        14. World.zip
          7.78 MB

            Unassigned Unassigned
            DiamondDragon721 Orbic
            Votes:
            36 Vote for this issue
            Watchers:
            20 Start watching this issue

              Created:
              Updated:
              CHK: