Skip to content

fix culling orientation, fabric feature renderer face filtering, sprite bounds check, and multithreading crashes - #468

Open
Spagles wants to merge 6 commits into
FxMorin:masterfrom
Spagles:master
Open

fix culling orientation, fabric feature renderer face filtering, sprite bounds check, and multithreading crashes#468
Spagles wants to merge 6 commits into
FxMorin:masterfrom
Spagles:master

Conversation

@Spagles

@Spagles Spagles commented Aug 15, 2026

Copy link
Copy Markdown
Contributor
  • Fixed adjacent wall face orientation in painting back-face culling (CullingUtils#shouldCullPaintingBack):

    • What: Changed moreculling$getFaceCullingShape(oppositeDir) to query oppositeDir.getOpposite().
    • Why: The wall block behind the painting is located at posBehind = paintingPos.relative(oppositeDir). The face of that wall block that abuts the painting is its opposite face (oppositeDir.getOpposite()), pointing back towards the painting. Querying oppositeDir evaluated the far side of the wall block rather than the contact surface, leading to incorrect occlusion tests and visual artifacts when paintings were placed against directional or non-solid blocks.
  • Restored face culling filtering in the Fabric block model feature renderer (MorecullingFabricBlockModelFeatureRenderer):

    • What: Passed submit to putPartQuads and guarded quad additions with submit.shouldCull(direction) and submit.shouldCull(quad.direction()).
    • Why: When running on Fabric with FRAPI active, putPartQuads previously iterated over all model part quads and submitted them unconditionally. This bypassed directional face culling rules defined by submit types like BlockModelSubmitWithoutFace or BlockModelSubmitForFace, rendering all faces and defeating optimizations.
  • Forwarded quad bounds in sprite transparency checks (TextureAtlasSprite_opacityMixin):

    • What: Updated moreculling$hasTransparency(QuadBounds bounds) to pass bounds to SpriteUtils.doesHaveTransparency(...).
    • Why: The overload previously ignored the provided QuadBounds argument and evaluated the entire sprite image. This caused quads whose specific UV region was completely opaque to be falsely identified as transparent if any other unrelated area of the texture atlas contained transparent pixels.
  • Added null check for bakedModelManager during cache resets (CacheUtils#resetAllCache):

    • What: Wrapped the model translucency cache reset loop in an if (bakedModelManager != null) guard.
    • Why: bakedModelManager is populated during client setup. If a resource reload event fires before the model manager field is captured, calling bakedModelManager.getBlockStateModelSet() threw an unhandled NullPointerException that crashed the client during startup.
  • Eradicated shared mutable state in platform helper singletons (FabricPlatformHelper & NeoForgePlatformHelper):

    • What: Removed the instance-level parts collection field and allocated the list locally inside getQuads().
    • Why: Platform helpers are shared global singletons accessed via Services.PLATFORM. In multi-threaded rendering pipelines where chunk baking and model translucency caching occur across multiple worker threads simultaneously, sharing and clearing a single mutable list instance caused data races, missing quads, and ConcurrentModificationException crashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant