fix(motionblur): stop per-frame ShaderGroup leak and edge-row artifacts - #161
Merged
Conversation
New mode reloaded both motionblur post shaders whenever the active group name did not match, and vanilla loadShader never deletes the previous ShaderGroup. On systems where the GLSL 150 variant fails to compile (macOS legacy GL context), this leaked two fullscreen framebuffers every frame until VRAM exhaustion corrupted the screen (garbage pixel rows / top-half artifacts). - delete the old shader group (stopUseShader) before loading, load only the GLSL 120 variant, and never retry after a failed load - rebind the main framebuffer after loadShader, which leaves FB 0 bound - accept the loaded group's own name in isUsingShader instead of the motionblur_core name, which could never match the 120 variant - drop the motionblur_core assets: 1.8.9 runs a compatibility context and the program mixed a #version 120 vertex shader with a #version 150 fragment shader, which is link-error territory anyway - cache the listShaders reflection Field and fall back to the searge name so Strength works in the remapped production jar - Old mode: use float division for the fullscreen quad size so the bottom/right remainder rows are covered, and push/pop the projection and modelview matrices around blur() Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Users report intermittent screen corruption with MotionBlur enabled: a few garbage pixel rows, or the whole top half of the screen rendering garbage.
Root cause (New mode, the default):
renderOverlayreloaded both post shaders every timeisUsingShader()returned false, and vanillaEntityRenderer.loadShadernever deletes the previousShaderGroup. The GLSL 150 variant (motionblur_core) mixes a#version 120vertex shader (vanillasobel.vsh) with a#version 150fragment shader and cannot compile in the legacy GL context 1.8.9 gets on macOS. When it fails,useShaderstays false, the name check inisUsingShader()(which only accepted the core variant's name) never matches, and the module reloads both shaders every frame — leaking two fullscreen framebuffers (color + depth) per frame until VRAM exhaustion corrupts rendering. Even where both variants load, one full ShaderGroup leaked on every activation / respawn / dimension change.Fix
stopUseShader()) before loading, load only the GLSL 120 variant, and never retry after a failed load (log instead).loadShader, which leaves FB 0 bound mid-frame.isUsingShader()now checks for the shader that is actually loaded.motionblur_coreassets (unreferenced now; the 120 pipeline runs everywhere 1.8.9 runs).listShadersreflectionFieldwith a searge-name (field_148031_d) fallback so the Strength setting also works in the remapped production jar, and log instead of silently swallowing reflection failures.width / scaleFactor), leaving up toscaleFactor-1unprocessed pixel rows/columns at the bottom/right edge ("a few abnormal pixel rows"); now float division. Also push/pop the projection/modelview matrices aroundblur()instead of clobbering them.Testing
./gradlew compileJavapasses.EntityRenderer.loadShader/ShaderGroup/ShaderLoader): load-shader leak, compile-failure path, and searge field name confirmed.🤖 Generated with Claude Code