🪧 2-Sided Sign & Hanging Sign Text Culling (Minecraft 26.1.2)
In Minecraft 26.1.2, signs feature two-sided text rendering (getFrontText() and getBackText()). The game's font rendering engine draws glyph quads, colors, and glow outlines on both sides simultaneously.
Camera Culling eliminates unnecessary text rendering passes via normal vector dot products ($\vec{N} \cdot \vec{V}$) and empty-text fast passes.
📋 Sign Culling Infobox
| Property | Value |
|---|---|
| Target Pipeline | BlockEntityRenderDispatcher.tryExtractRenderState @At("RETURN") |
| API Hook | signState.frontText = null; / signState.backText = null; |
| Supported Types | Wall Signs, Standing Signs, Wall Hanging Signs, Ceiling Hanging Signs |
| Empty Fast-Pass | Automatically skips blank faces with zero text characters |
| Dot Product Margin | Tolerance of $\pm 0.05$ prevents edge-angle pop-in |
📐 Vector Normal Dot-Product Mathematics
$$\vec{V} = (X_{\text{cam} - (X_{\text{sign} + 0.5), Z_{\text{cam} - (Z_{\text{sign} + 0.5))$$
1. Wall Signs & Wall Hanging Signs
Derived directly from block Direction step offsets: $$N_x = \text{facing.getStepX()}, \quad N_z = \text{facing.getStepZ()}$$
2. Standing Signs & Ceiling Hanging Signs
$$\theta = \left(\frac{\text{rotation} \times 360^\circ}{16}\right) \times \frac{\pi}{180}$$ $$N_x = -\sin\theta, \quad N_z = \cos\theta$$
3. Visibility Determination
$$D = N_x V_x + N_z V_z$$
- Front Text: Culled when $D < -0.05$.
- Back Text: Culled when $D > 0.05$.
⚡ Empty-Side Fast-Pass
public static boolean isTextEmpty(SignText text) {
if (text == null) return true;
for (int i = 0; i < 4; i++) {
Component msg = text.getMessage(i, false);
if (msg != null && !msg.getString().trim().isEmpty()) {
return false;
}
}
return true;
}Blank faces are nulled out immediately without calculating dot products.
