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

Transparency layers lose their auxiliary depth buffer ID when resized

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: 1.16.1
    • Fix Version/s: 20w27a
    • Labels:
      None
    • Confirmation Status:
      Community Consensus
    • Category:
      Rendering

      Description

      Comments and in-depth analysis by Nicholas Miell stripped from MC-187411.

      This appears to be a problem on your end.

      Minecraft renders to six layers:

      • Diffuse (framebuffer 2, color0: texture 6, depth: texture 7)
      • ItemEntity (framebuffer 30, color0: texture 97, depth: texture 98)
      • Translucent (framebuffer 29, color0: texture 95, depth: texture 96)
      • Particles (framebuffer 31, color0: texture 99, depth: texture 100)
      • Clouds (framebuffer 32, color0: texture 101, depth: texture 102)
      • Weather (framebuffer 33, color0: texture 103, depth: texture 104)

      However, when it comes time to blend these layers together, the samplers in the shader are as follows:

      • DiffuseSampler: 6 (Diffuse layer color0)
      • DiffuseDepthSampler: 7 (Diffuse layer depth)
      • TranslucentSampler: 95 (Translucent layer color0)
      • TranslucentDepthSampler: 82
      • ItemEntitySampler: 97 (ItemEntity layer color0)
      • ItemEntityDepthSampler: 84
      • ParticlesSampler: 99 (Particles layer color0)
      • ParticlesDepthSampler): 86
      • CloudsSampler: 101 (Clouds layer color0)
      • CloudsDepthSampler: 88
      • WeatherSampler: 103 (Weather layer color0)
      • WeatherDepthSampler: 90


      Looking at the apitrace some more, it looks like you e.g. replace textures 81 and 82 with 95 and 96. I bet you're saving the new texture ID for TranslucentSampler but forgetting to save the new TranslucentDepthSampler texture ID at the same time.

      3134239 glBindFramebuffer(target = GL_FRAMEBUFFER, framebuffer = 0)
      3134240 glDeleteTextures(n = 1, textures = &82)
      3134241 glDeleteTextures(n = 1, textures = &81)
      3134242 glBindFramebuffer(target = GL_FRAMEBUFFER, framebuffer = 0)
      3134243 glDeleteFramebuffers(n = 1, framebuffers = &22)
      3134244 glGenFramebuffers(n = 1, framebuffers = &29)
      3134245 glGenTextures(n = 1, textures = &95)
      3134246 glGenTextures(n = 1, textures = &96)
      3134247 glBindTexture(target = GL_TEXTURE_2D, texture = 96)
      3134248 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MIN_FILTER, param = GL_NEAREST)
      3134249 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MAG_FILTER, param = GL_NEAREST)
      3134250 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_S, param = GL_CLAMP)
      3134251 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_T, param = GL_CLAMP)
      3134252 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_COMPARE_MODE, param = GL_ZERO)
      3134253 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_DEPTH_COMPONENT, width = 1280, height = 720, border = 0, format = GL_DEPTH_COMPONENT, type = GL_FLOAT, pixels = NULL)
      3134254 glBindTexture(target = GL_TEXTURE_2D, texture = 95)
      3134255 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MIN_FILTER, param = GL_NEAREST)
      3134256 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MAG_FILTER, param = GL_NEAREST)
      3134257 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_S, param = GL_CLAMP)
      3134258 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_T, param = GL_CLAMP)
      3134259 glBindTexture(target = GL_TEXTURE_2D, texture = 0)
      3134260 glBindTexture(target = GL_TEXTURE_2D, texture = 95)
      3134261 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA8, width = 1280, height = 720, border = 0, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = NULL)
      3134262 glBindFramebuffer(target = GL_FRAMEBUFFER, framebuffer = 29)
      3134263 glFramebufferTexture2D(target = GL_FRAMEBUFFER, attachment = GL_COLOR_ATTACHMENT0, textarget = GL_TEXTURE_2D, texture = 95, level = 0)
      3134264 glFramebufferTexture2D(target = GL_FRAMEBUFFER, attachment = GL_DEPTH_ATTACHMENT, textarget = GL_TEXTURE_2D, texture = 96, level = 0)
      3134265 glCheckFramebufferStatus(target = GL_FRAMEBUFFER) = GL_FRAMEBUFFER_COMPLETE
      3134266 glBindFramebuffer(target = GL_FRAMEBUFFER, framebuffer = 29)


      OK, so your shader class has List<String> holding sampler names and a List<Object> which can either hold instances of your framebuffer class, instances of your texture class, or a boxed integer representing a raw OpenGL texture ID.

      If the list entry is a framebuffer class instance, you use the instances's OpenGL color attachment ID member variable, if it is a texture class instance you use the instance's OpenGL texture ID member variable, and if it is an Integer object you use the integer directly.

      When you're parsing the shader JSON, textures are inserted by boxed Integer ID (you don't seem to ever insert texture class instances even though this is technically supported), auxiliary color samplers are inserted as framebuffer class instances, and auxillary depth samplers are inserted by the boxed Integer ID of the framebuffer instance's depth attachment.

      Your framebuffer class supports reinitialization where it deletes the OpenGL framebuffer object and the OpenGL texture objects and then creates new OpenGL textures and and new OpenGL framebuffer in-place. When this happens, though, it never gets communicated back to the shader class instance that has a reference to the framebuffer class instance. So because the shader class rereads the framebuffer class's color attachment ID every time it uploads the uniforms, the correct color texture is used, but since the depth texture ID is only read once when the JSON is originally parsed, it'll continue using the stale value from the original framebuffer class instance.

      Presumably the framebuffer class only gets reinitialized on Mesa for some reason and never gets reinitialized on other platforms, which is why this appears to be a Mesa-only problem. Or maybe the other platforms immediately reuse the deleted textures IDs, and the stale depth texture ID happens to get reused as the new depth texture ID by pure luck.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              xilefian [Mojang] Felix Jones
              Reporter:
              OpterSaiher Dawn Sunset
              Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                CHK: