File Details
azurelib-fabric-1.21.1-3.1.10.jar
- R
- Jun 17, 2026
- 871.08 KB
- 1.4K
- 1.21.1
- Fabric + 1
File Name
azurelib-fabric-1.21.1-3.1.10.jar
Supported Versions
- 1.21.1
Curse Maven Snippet
v3.1.10
Performance — Rendering Pipeline Overhaul
This release is a focused performance pass targeting the client-side rendering pipeline. The goal was to bring per-entity CPU and GC cost for complex animated models in line with vanilla mob rendering. All changes are backwards-compatible — no model files, animator classes, or existing renderer configurations require modification.
Fixes
- Fixed registry of easing types (Credit to Collinvh for fix)
- Fixed bedrock easing interpolation having the position incorrectly in the place of the first value. (Credit to Collinvh for fix)
- Fixed broken matrix translation in
RenderUtils.translateMatrix. The previous implementation usedMatrix4f.add()to apply a translation vector, which is mathematically incorrect and produced wrong world-space matrix results for bone tracking. Now usesMatrix4f.translate()as intended. - Fixed triple
boneTextureOverrideProvidercall per bone. The provider lambda was invoked three times per bone per frame ingetOrRefreshRenderBuffer. Now called once, result cached locally. - Replaced per-cube
pushPose/popPosewith save/restore inrenderCubesOfBone. The pose stack entry is now captured once per bone and restored after each cube transform, eliminating N matrix stack copies per multi-cube bone. - Added hidden bone early-out to
renderRecursively. Hidden bones now skip all matrix work (pushPose, translate, rotate, scale) entirely. Children are still iterated unlessisHidingChildren()is also true, matching Bedrock's bone visibility spec. - Hoisted flat-cube check out of the quad loop in
renderCube.fixInvertedFlatCubeis only relevant for 2D plane cubes (one dimension = 0). The check is now computed once per cube before the quad loop and skipped entirely for standard 3D cubes. - Eliminated per-vertex redundant reads in
createVerticesOfQuad.getTextureOverride(),packedOverlay(),packedLight(), and normal vector components are now all hoisted outside the vertex loop. UV scale factors for the texture override path are pre-computed as floats, replacing two integer divisions per vertex with a single multiply. - Fixed
invertAndMultiplyMatricesallocation. Previously allocated anew Matrix4fon every call (called twice per tracked bone per frame). Now uses a staticINVERT_SCRATCHbuffer; one allocation per call for the returned result only. - Eliminated per-frame
Matrix4fheap allocations inrenderRecursively. The twonew Matrix4f(...)calls in the bone matrix tracking path are replaced with reusablescratchPoseStateandscratchLocalMatrixinstance fields. - Fixed triple
getAdjustedTick()call. Was called once before the bone loop, once inside the loop per bone, and once for the callback. Now called once;currentAdjustedTickfield reused throughout. - Fixed severe per-frame allocation spam. The previous implementation called
CubicBezierCurve.getPoints(200)on every bezier keyframe every frame, allocating anArrayListand 201Vector2dobjects per call. AdditionallyfindClosestPointsallocated two moreVector2dinstances and aVector2d[]return on every call, andbuildBezierCurveallocated fourVector2dcontrol points per call. For a model with multiple bezier-eased bones this produced 240+ allocations per frame contributing significantly to GC pressure. - Fixed AzArmorRendererPipeline using head for the leftArm scaling.
- Fixed custom easing type lookup when easing names use mixed or lower camel case.
Changed
- Replaced nine
ArrayDeque<AzAnimationPoint>queues with a flat object pool. Nine pre-allocatedAzAnimationPointinstances are reused every frame viaset(). Aboolean[9]presence array replaces queue state. This eliminates the dominant source of per-frame heap allocation in the animation pipeline — previously ~180 record allocations per animated bone per frame. - Removed
LinkedListusage. Previously used for all nine queues before theArrayDequeinterim; now eliminated entirely. - Converted from
recordto mutablefinal class. All record accessor names preserved for API compatibility. Newset(...)method enables in-place reuse by the pool inAzBoneAnimationQueue. - Converted from
recordto mutablefinal class. Newset(T, double)method allows the single scratch instance onAzAbstractKeyframeExecutorto be truly reused end-to-end with zero allocation. - Replaced linear keyframe scan with binary search.
getCurrentKeyframeLocationpreviously walked all keyframes from the start (O(n)). Now builds a cumulative end-time array and binary searches it (O(log n)). Meaningful for animations with many keyframes per bone. - Add overload method for per bone Texture/Render Type to support the entity as well.
- Replaced per-frame
DoubleSupplierlambda allocation forANIM_TIME. A stableanimTimeSupplierfield closes overcurrentAdjustedTick;setMemoizedValuereceives the same object reference every frame. - Replaced per-frame
DoubleSupplierlambda allocation forANIM_TIME, matching the fix inAzKeyframeExecutor. - Replaced four per-frame
DoubleSupplierlambda/method-reference allocations inapplyMolangQueries.LIFE_TIME,ACTOR_COUNT,TIME_OF_DAY, andMOON_PHASEnow use stable supplier fields that read mutable double fields set before each call. - Updated to use pool-based
pollRotX/Y/Z,pollPosX/Y/Z,pollSclX/Y/Zaccessors from the newAzBoneAnimationQueuepool design. - Replaced point-scan lookup with binary search on curve parameter
t. Rather than sampling the curve at 200 evenly-spaced points and scanning for the nearest two, the curve is now evaluated via binary search ont(20 iterations), exploiting the monotonically increasing x-coordinate of well-formed animation curves. Converges to the same result with zero heap allocation. - Added
translateMatrixInPlace(Matrix4f, Vector3f). Mutates the matrix directly, for call sites that already own the matrix and don't need the original preserved. - Removed
getPoints(int). No longer needed now thatevaluateAtTimehandles all call sites.
Added
- Added hidden bone early-out matching
AzModelRenderer, beforepushPoseand all transform calls. - Added scratch
AzKeyframeLocationfield. The single instance is reused across allgetAnimationPointAtTickcalls via.set(), eliminating one record allocation per axis per bone per frame. - Added
prepareFrame()method. Clears all pool presence flags before the keyframe executor writes new values each frame, preventing stale values from partially-animated prior frames bleeding through. - Added
boneAnimationQueueCache.prepareFrame()call beforestateMachine.update()in the per-frame update order. - Added reusable scratch fields. Four
Vector2dfields replace the per-call control point allocations inbuildBezierCurve, and two scratchVector2dfields are passed intoCubicBezierCurve.evaluateAtTimefor the binary search iterations. - Added
evaluateAtTime(double, Vector2d, Vector2d). Zero-allocation curve evaluation using binary search ont, accepting caller-provided scratch vectors. Replaces the allocation-heavygetPoints(int)approach. - Configures bone hierarchy depth culling and animation tick-rate reduction, each with independent distance thresholds.
AzLodConfig.DISABLED— no LOD applied.AzLodConfig.DEFAULT— automatically applied to all entity renderers unless overridden: bone LOD at 20 blocks (depth ≤ 3), animation LOD at 28 blocks (every 2 ticks).
- Per-entity runtime manager. Walks the bone tree and calls
setHidden(true)on bones exceeding the depth budget. Tracks alodHiddenflag so LOD-hidden bones can be restored when the entity returns to close range without affecting model-authored hidden bones. - Returns a
shouldAnimateboolean to gate the full animation pipeline update, implementing tick-rate reduction for distant entities. - Added
withLodConfig(AzLodConfig)builder method. Defaults toAzLodConfig.DEFAULTwhen not specified. - Wires
AzLodManagerinto the render loop. LOD manager is instantiated per entity UUID and updated each frame before the pipeline runs. WhenshouldAnimateis false the model renders at its last computed pose, skipping all animation controller work. - Added
lodHiddenfield withgetLodHidden()/setLodHidden(boolean)accessors. Distinguishes LOD-driven visibility from model-authoreddontRenderflags. Propagated throughdeepCopy().

