Skip to content

⏱️ Временной гистерезис и нулевое выделение памяти (Minecraft 26.3) ​

Высокоскоростное окклюзионное отсечение может порождать две распространенные проблемы производительности:

  1. Мерцание на границах обзора (Z-Fighting / Boundary Pop-in): Небольшие повороты камеры или покачивание при ходьбе, пересекающие ребро блока, могут приводить к быстрому чередованию видимого и скрытого состояния сущности на соседних кадрах.
  2. Задержки из-за сборки мусора: Непрерывное выделение объектов new Vec3() и ограничивающих рамок во время трассировки лучей вызывает частые паузы сборщика мусора JVM Young-Gen.

Camera Culling решает обе проблемы с помощью адаптивного буфера задержки в зависимости от расстояния и движка критического пути с нулевым выделением памяти.


📋 Инфобокс движка гистерезиса ​

ПараметрЗначение
Ближний буфер задержки$d \le 32\text{m} \implies 4\text{ кадра}$ стабильности перекрытия
Средний буфер задержки$32\text{m} < d \le 64\text{m} \implies 8\text{ кадров}$ стабильности перекрытия
Дальний буфер задержки$d > 64\text{m} \implies 12\text{ кадров}$ стабильности перекрытия
Задержка отображения (Unculling)Мгновенно ($0\text{ кадров}$ задержки при первом же луче)
Выделение памяти в куче$0\text{ байт/кадр}$ (примитивные координаты double)

📐 Формула буфера задержки в зависимости от расстояния ​

Требуемая серия кадров перекрытия (occlusion streak) перед переводом сущности в состояние [CULLED] рассчитывается следующим образом:

$$\text{RequiredStreak}(d) = \begin{cases} 12\text{ кадров} & \text{если } d^2 > 64.0^2 \ (4096.0\text{m}^2) \ 8\text{ кадров} & \text{если } d^2 > 32.0^2 \ (1024.0\text{m}^2) \ 4\text{ кадра} & \text{иначе} \end{cases}$$

text
Entity Sightline Lost
  ├── Frame 1 occluded ──► Grace State (Still Rendered)
  ├── Frame 2 occluded ──► Grace State (Still Rendered)
  ├── Frame 3 occluded ──► Grace State (Still Rendered)
  └── Frame 4 occluded ──► CULL (Streak Met)
  • Мгновенная отмена отсечения: Как только хотя бы одна точка выборки трассировки подтверждает прямую видимость, счетчик перекрытия сбрасывается (OCCLUDED_STREAK.remove(id)), делая сущность видимой с нулевой задержкой ($0\text{ кадров}$).
  • Асимметричное затухание: Для отсечения требуется несколько последовательных кадров скрытия, а для отображения достаточно 1 кадра. Это полностью устраняет мерцание при поворотах камеры.

⚡ Движок критического пути с нулевым выделением памяти ​

В CullingRaycastHelper.java промежуточные выделения векторов в куче полностью устранены:

java
// Нулевое выделение в куче: координаты передаются в виде примитивных double
public static boolean hasLineOfSight(Level level, Vec3 from, double toX, double toY, double toZ) {
    Vec3 to = new Vec3(toX, toY, toZ);
    ClipContext ctx = new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, CollisionContext.empty());
    BlockHitResult hit = level.clip(ctx);
    if (hit.getType() == HitResult.Type.MISS) {
        return true;
    }
    // Оценка попадания в пол и допусков без конструирования объектов
    ...
}

🔗 Связанные страницы ​

Official documentation & web portal for Dasik Igaijinn mods.