🖥️ Client-Side Anisotropic Chunk Mesh Prioritization (MC 26.3)
📌 Repository Source Disclaimer: The documentation in this Wiki reflects the current source code state in the repository, which may include recent unreleased commits or developmental features ahead of public release builds on CurseForge and Modrinth.
1. Official Infobox Table
| Parameter | Technical Details |
|---|---|
| Subsystem Name | Anisotropic Chunk Mesh Prioritization |
| Minecraft Anchor | MC 26.3 |
| Java Implementation | net.vanillaoutsider.velocityrender.math.AnisotropicDistanceHelper |
| Client Polling Mixin | net.vanillaoutsider.velocityrender.client.mixin.SectionTaskDynamicQueueMixin |
| Vanilla Target Class | net.minecraft.client.renderer.chunk.SectionTaskDynamicQueue |
| Target Method | poll() |
| Redirect Call | Lnet/minecraft/core/BlockPos;distToCenterSqr(Lnet/minecraft/core/Position;)D |
| Controlling GameRules | velocityrender:enabled, velocityrender:forward_lead_multiplier, velocityrender:min_speed_threshold_pct |
| Default Activation Speed | $0.20\text{ blocks/tick} = 4.0\text{ m/s}$ |
| Maximum Lead Offset | $256.0\text{ blocks}$ (16 Chunks ahead) |
2. Step-by-Step Player Workflow & Behavior
+----------------------------------------+
| Player Traversal (Walking / Running / |
| Riding Horse / Elytra Flight) |
+----------------------------------------+
|
v
[ ClientTickEvents.END_CLIENT_TICK ]
|
v
[ ClientVelocityTracker.clientTick() ]
/ \
(Speed < 0.20 b/t) (Speed >= 0.20 b/t)
| |
v v
+-----------------------+ +-----------------------------+
| activeBias = false | | activeBias = true |
| cachedLeadOffset = 0 | | Compute normalized dx,dy,dz |
| Vanilla Radial Sphere | | cachedLeadOffset = v * 16 |
+-----------------------+ +-----------------------------+
| |
+--------------------+---------------------+
|
v
[ SectionTaskDynamicQueue.poll() ]
|
v
[ calculateBiasedDistanceSqr() ]
|
Forward terrain scored lower!
Compiled and rendered FIRST on screen!- Stationary & Walking Phase ($s < 0.20\text{ b/t}$):
- The velocity tracking engine detects normal movement below threshold.
ClientVelocityTracker.activeBiasremainsfalse.- Chunk compile tasks are sorted by standard radial Euclidean distance.
- Accelerated Travel Phase ($0.20 \le s < 0.50\text{ b/t}$):
- When sprinting or galloping on a horse, velocity reaches $0.25 - 0.45\text{ b/t}$.
- Directional biasing activates, extending forward lead offset between $32$ and $64$ blocks ahead.
- Terrain directly in front of the horse or player appears seamlessly without visible draw-in.
- Hyper-Velocity Phase ($s \ge 0.50\text{ b/t}$):
- Rocket-boosted Elytra flight, ice boating on blue ice, or minecart hyper-rails ($s = 1.0 - 2.5\text{ b/t}$).
- Maximum directional lead offset clamps up to $256.0\text{ blocks}$ ($16$ chunks ahead).
- The render scheduler prioritizes an aerodynamic cone centered along the player's flight vector, eliminating void walls and abrupt mountain pop-in.
3. Mathematical Foundations & Equations
Exponential Moving Average (EMA) Velocity Smoothing
Raw entity delta coordinates $\Delta x, \Delta y, \Delta z$ can jitter during rapid mouse movement. An exponential moving average with smoothing constant $\alpha = 0.65$ eliminates noise while ensuring instant physical response:
$$\vec{v}{\text{eff}} = \begin{cases} \Delta\vec{P} & \text{if } |\Delta\vec{P}| > 0.001 \ \vec{v}{\text{raw}} & \text{otherwise} \end{cases}$$
$$\vec{v}{\text{smooth}} = \alpha \cdot \vec{v}{\text{eff}} + (1.0 - \alpha) \cdot \vec{v}_{\text{smooth}}, \quad \alpha = 0.65$$
Speed Magnitude & Unit Vector Normalization
$$s = |\vec{v}_{\text{smooth}}| = \sqrt{v_x^2 + v_y^2 + v_z^2}$$
$$\vec{d}{\text{norm}} = \begin{cases} \frac{\vec{v}{\text{smooth}}}{s} & \text{if } s > 10^{-4} \ \vec{0} & \text{otherwise} \end{cases}$$
Anisotropic Directional Dot-Product Distance Bias
For each chunk render section origin $\vec{P}{\text{section}}$ relative to camera position $\vec{P}{\text{cam}}$:
$$\Delta\vec{P} = (\vec{P}{\text{section}} + 0.5) - \vec{P}{\text{cam}}$$
$$\text{EuclideanDistSqr} = \Delta x^2 + \Delta y^2 + \Delta z^2$$
$$\text{DotProduct} = \vec{d}_{\text{norm}} \cdot \Delta\vec{P} = d_x \Delta x + d_y \Delta y + d_z \Delta z$$
$$\text{LeadOffset} = \min\left(256.0,, s \times 16.0 \times \frac{\text{leadMultiplier}}{100}\right)$$
$$\text{BiasedDistSqr} = \max\left(0.0,, \text{EuclideanDistSqr} - 2.0 \cdot \text{DotProduct} \cdot \text{LeadOffset}\right)$$
When a chunk section lies ahead ($\text{DotProduct} > 0$), its distance score is reduced by up to $2 \cdot \text{DotProduct} \cdot \text{LeadOffset}$, placing it at the front of the compile queue. When behind ($\text{DotProduct} < 0$), the subtraction becomes an addition, deferring rear compilation.
4. Visual ASCII Diagram: Radial Sorting vs Anisotropic Cone
VANILLA RADIAL SORTING ANISOTROPIC VELOCITY BIAS
(Equal priority in all directions) (Elongated aerodynamic cone ahead)
. - ~ ~ - . . - ~ ~ - .
. . . : .
. . . : .
. ^ . . +----+----+ .
. | . . | CHUNK | .
. <-- [P] --> . . | AHEAD 1 | .
. | . . +----+----+ .
. v . . | CHUNK | .
. . . | AHEAD 2 | .
. . . +----+----+ .
. - ~ ~ - . . | .
. - ~ ~ [P] ~ ~ - .
(v)5. Hot-Path Memory & Volatile State Schema
To guarantee $O(1)$ lock-free access across render worker threads polling at multi-gigahertz rates:
HotPathCache (volatile in ClientVelocityTracker):
├── activeBias: boolean // Gating boolean flag
├── cachedNormDx: double // Normalized X flight vector component
├── cachedNormDy: double // Normalized Y flight vector component
├── cachedNormDz: double // Normalized Z flight vector component
└── cachedLeadOffset: double // Clamped lookahead reach (0.0 to 256.0)6. Exhaustive Reference Tables
| Travel Mode | Velocity ($s$) | Velocity (m/s) | Active Bias | Lead Offset | Meshing Prioritization Reach |
|---|---|---|---|---|---|
| Idle / Stationary | $0.00\text{ b/t}$ | $0.0\text{ m/s}$ | false | $0.0\text{ blocks}$ | Standard vanilla radial meshing |
| Walking | $0.11\text{ b/t}$ | $2.2\text{ m/s}$ | false | $0.0\text{ blocks}$ | Standard vanilla radial meshing |
| Sprinting | $0.28\text{ b/t}$ | $5.6\text{ m/s}$ | true | $44.8\text{ blocks}$ | Forward $2 - 3$ chunk bias |
| Horse Gallop | $0.45\text{ b/t}$ | $9.0\text{ m/s}$ | true | $72.0\text{ blocks}$ | Forward $4 - 5$ chunk bias |
| Elytra Glide | $1.20\text{ b/t}$ | $24.0\text{ m/s}$ | true | $192.0\text{ blocks}$ | Forward $12$ chunk aerodynamic cone |
| Elytra Firework Rocket | $1.80\text{ b/t}$ | $36.0\text{ m/s}$ | true | $256.0\text{ blocks}$ (Clamped) | Maximum $16$ chunk forward priority |
| Ice Boat Hyperway | $2.40\text{ b/t}$ | $48.0\text{ m/s}$ | true | $256.0\text{ blocks}$ (Clamped) | Maximum $16$ chunk forward priority |
7. Developer & Mixin Hooks
Mixin Implementation Snippet
// Target Class: SectionTaskDynamicQueue
@Mixin(SectionTaskDynamicQueue.class)
public abstract class SectionTaskDynamicQueueMixin {
@Redirect(
method = "poll",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/core/BlockPos;distToCenterSqr(Lnet/minecraft/core/Position;)D"
)
)
private double youRunFast$biasedDistance(BlockPos origin, Position cameraPos) {
return AnisotropicDistanceHelper.calculateBiasedDistanceSqr(origin, cameraPos);
}
}Key Java Method Signatures
AnisotropicDistanceHelper.calculateBiasedDistanceSqr(BlockPos origin, Position cameraPos): Fast-path method executed per candidate section.ClientVelocityTracker.clientTick(Minecraft client): Updates EMA velocity and volatile cache every client tick.ClientVelocityTracker.setLeadMultiplier(double value): Dynamically tunes lookahead stretch factor.
