Keep entity occlusion culling off block entities

Keep block entity frustum checks and section cache rendering independent of the ordinary entity occlusion culler. Show mode-specific culling help in the graphics UI.

Co-Authored-By: OpenAI Codex <[email protected]>
This commit is contained in:
ElyTheCatandOpenAI Codex committed 2026-11-02 08:04:05 +03:30
1 parent e12185820a
commit 778dad1e4a
13 files changed
+46 -14

No files matched your search

@@ -207,7 +207,7 @@ pub fn rows(level: Level) -> Vec<Row> {
h(
H::EntityCulling,
None,
"Hides models behind opaque blocks. Async checks off-thread; entities tick.",
"Hides entities behind opaque blocks.",
),
h(
H::LeafCulling,
@@ -470,6 +470,11 @@ fn description(item: Item, s: &Settings, text: &'static str) -> &'static str {
(Item::Horizon(H::HdrPeak | H::HdrPaperWhite), Setup::Automatic | Setup::Changed) => {
"Set up for your display. Leave on Auto unless it looks wrong."
}
(Item::Horizon(H::EntityCulling), _) => match s.horizon.entity_culling {
EntityCullingMode::Off => "No entity occlusion culling.",
EntityCullingMode::Synchronous => "CPU occlusion test runs this frame.",
EntityCullingMode::Asynchronous => "Occlusion checks run on a worker thread.",
},
(Item::Horizon(H::LeafCulling), _) => match s.horizon.leaf_culling {
LeafCullingMode::Off => "Every leaf face. Vanilla's fancy leaves.",
LeafCullingMode::Solid => {
@@ -166,6 +166,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Wie weit Kreaturen, Pflanzen und Maschinen weiterarbeiten. Kostet CPU-Zeit.",
"How far away mobs and items are drawn, as a share of normal.": "Zeichenweite für Kreaturen und Gegenstände, anteilig zur Norm.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Überspringt Gelände hinter geschlossenen Abschnitten. Aus kostet viel.",
"Hides entities behind opaque blocks.": "Versteckt Entitäten hinter undurchsichtigen Blöcken.",
"No entity occlusion culling.": "Keine Verdeckungserkennung für Entitäten.",
"CPU occlusion test runs this frame.": "Die CPU prüft die Verdeckung in diesem Frame.",
"Occlusion checks run on a worker thread.": "Verdeckungsprüfungen laufen in einem Worker-Thread.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Mesh-Abschnitte pro Bild. Weniger: flüssigeres Laden.",
"Soft shadows in corners. Costs chunk building time only.": "Weiche Schatten in Ecken. Kostet nur Zeit beim Chunk-Aufbau.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Kleinere Textur-Kopien für fernes Gelände: weniger Flimmern.",
@@ -170,6 +170,10 @@
"How far mobs, crops and machines keep working. CPU time.": "How far mobs, crops and machines keep working. CPU time.",
"How far away mobs and items are drawn, as a share of normal.": "How far away mobs and items are drawn, as a share of normal.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Skips terrain hidden behind closed sections. Off costs a lot.",
"Hides entities behind opaque blocks.": "Hides entities behind opaque blocks.",
"No entity occlusion culling.": "No entity occlusion culling.",
"CPU occlusion test runs this frame.": "CPU occlusion test runs this frame.",
"Occlusion checks run on a worker thread.": "Occlusion checks run on a worker thread.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Meshed sections uploaded per frame. Lower is smoother while loading.",
"Soft shadows in corners. Costs chunk building time only.": "Soft shadows in corners. Costs chunk building time only.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Smaller copies of block textures for distant terrain: less shimmer.",
@@ -158,6 +158,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Hasta dónde siguen funcionando mobs, cultivos y máquinas. Tiempo de CPU.",
"How far away mobs and items are drawn, as a share of normal.": "A qué distancia se dibujan mobs y objetos, como proporción de lo normal.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Omite el terreno oculto tras secciones cerradas. Desactivarlo cuesta mucho.",
"Hides entities behind opaque blocks.": "Oculta entidades tras bloques opacos.",
"No entity occlusion culling.": "Sin oclusión de entidades.",
"CPU occlusion test runs this frame.": "La CPU comprueba la oclusión en este fotograma.",
"Occlusion checks run on a worker thread.": "Las comprobaciones de oclusión se ejecutan en un hilo de trabajo.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Secciones malladas subidas por fotograma. Menos es más fluido durante la carga.",
"Soft shadows in corners. Costs chunk building time only.": "Sombras suaves en las esquinas. Solo cuesta tiempo de construcción de chunks.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Copias más pequeñas de las texturas de bloques para el terreno lejano: menos parpadeo.",
@@ -166,6 +166,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Portée d'activité des créatures, cultures, machines. Coût : CPU.",
"How far away mobs and items are drawn, as a share of normal.": "Distance des créatures et objets, en part de la normale.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Ignore le terrain caché. Désactiver coûte cher.",
"Hides entities behind opaque blocks.": "Masque les entités derrière les blocs opaques.",
"No entity occlusion culling.": "Aucun masquage des entités occultées.",
"CPU occlusion test runs this frame.": "Le CPU teste l’occlusion sur cette image.",
"Occlusion checks run on a worker thread.": "Les tests d’occlusion s’exécutent sur un thread de travail.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Sections maillées par image. Moins : chargement plus fluide.",
"Soft shadows in corners. Costs chunk building time only.": "Ombres douces dans les coins. Coût : construction des chunks.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Textures réduites au loin : moins de scintillement.",
@@ -166,6 +166,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Jak daleko stworzenia, uprawy i maszyny nadal działają. Czas procesora.",
"How far away mobs and items are drawn, as a share of normal.": "Odległość rysowania stworzeń i przedmiotów, jako ułamek normy.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Pomija teren ukryty za zamkniętymi sekcjami. Wyłączone dużo kosztuje.",
"Hides entities behind opaque blocks.": "Ukrywa byty za nieprzezroczystymi blokami.",
"No entity occlusion culling.": "Bez odrzucania zasłoniętych bytów.",
"CPU occlusion test runs this frame.": "Test zasłonięcia wykonuje CPU w tej klatce.",
"Occlusion checks run on a worker thread.": "Testy zasłonięcia działają w wątku roboczym.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Liczba sekcji siatki wysyłanych na klatkę. Mniej to płynniej podczas ładowania.",
"Soft shadows in corners. Costs chunk building time only.": "Miękkie cienie w narożnikach. Kosztuje tylko czas budowania chunków.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Mniejsze kopie tekstur bloków dla odległego terenu: mniej migotania.",
@@ -157,6 +157,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Как далеко мобы, посевы и механизмы продолжают работать. Нагрузка на процессор.",
"How far away mobs and items are drawn, as a share of normal.": "С какой дистанции рисуются мобы и предметы, в долях от обычной.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Пропускает рельеф, скрытый за закрытыми секциями. Выключено — дорого.",
"Hides entities behind opaque blocks.": "Скрывает сущности за непрозрачными блоками.",
"No entity occlusion culling.": "Без отсечения сущностей по перекрытию.",
"CPU occlusion test runs this frame.": "В этом кадре проверку перекрытия выполняет CPU.",
"Occlusion checks run on a worker thread.": "Проверки перекрытия выполняются в рабочем потоке.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Секций меша за кадр. Меньше — плавнее во время загрузки.",
"Soft shadows in corners. Costs chunk building time only.": "Мягкие тени по углам. Замедляет только построение чанков.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Уменьшенные копии текстур блоков для дали: меньше мерцания.",
@@ -158,6 +158,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Yaratıkların, ekinlerin ve makinelerin ne kadar uzaktan çalışmaya devam edeceğini belirler. İşlemci gücü kullanır.",
"How far away mobs and items are drawn, as a share of normal.": "Yaratıkların ve eşyaların ne kadar uzaktan görüntüleneceğini, normal mesafeye oranla belirler.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Kapalı alanların arkasında kalan arazilerin çizilmesini önler. Kapalı olması ciddi performans kaybına neden olur.",
"Hides entities behind opaque blocks.": "Opak blokların arkasındaki varlıkları gizler.",
"No entity occlusion culling.": "Varlık oklüzyon ayıklaması kapalı.",
"CPU occlusion test runs this frame.": "Oklüzyon denetimini bu karede CPU yapar.",
"Occlusion checks run on a worker thread.": "Oklüzyon denetimleri bir iş parçacığında çalışır.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Her karede GPU'ya yüklenen oluşturulmuş bölüm sayısı. Daha düşük değerler yükleme sırasında daha akıcı bir deneyim sağlar.",
"Soft shadows in corners. Costs chunk building time only.": "Köşelerde yumuşak gölgeler oluşturur. Yalnızca parça oluşturma süresini etkiler.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Uzak arazilerde blok dokularının daha küçük kopyalarını kullanır. Titreşimli görüntüyü azaltır.",
@@ -166,6 +166,10 @@
"How far mobs, crops and machines keep working. CPU time.": "Як далеко працюють моби, посіви й механізми. Витрачає CPU.",
"How far away mobs and items are drawn, as a share of normal.": "Відстань малювання мобів і предметів, у частці від норми.",
"Skips terrain hidden behind closed sections. Off costs a lot.": "Пропускає приховану місцевість. Вимкнення коштує дорого.",
"Hides entities behind opaque blocks.": "Ховає сутності за непрозорими блоками.",
"No entity occlusion culling.": "Відсікання закритих сутностей вимкнено.",
"CPU occlusion test runs this frame.": "Цього кадру перекриття перевіряє CPU.",
"Occlusion checks run on a worker thread.": "Перевірки перекриття виконуються в робочому потоці.",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "Секцій сітки за кадр. Менше — плавніше під час завантаження.",
"Soft shadows in corners. Costs chunk building time only.": "М’які тіні в кутах. Витрачає лише час на побудову чанків.",
"Smaller copies of block textures for distant terrain: less shimmer.": "Менші копії текстур блоків для віддаленої місцевості: менше мерехтіння.",
@@ -160,6 +160,10 @@
"How far mobs, crops and machines keep working. CPU time.": "生物、农作物和机器持续工作的距离。占用 CPU 时间。",
"How far away mobs and items are drawn, as a share of normal.": "生物和物品的绘制距离,按正常值的比例。",
"Skips terrain hidden behind closed sections. Off costs a lot.": "跳过被封闭区块遮挡的地形。关闭的开销很大。",
"Hides entities behind opaque blocks.": "隐藏不透明方块后的实体。",
"No entity occlusion culling.": "不进行实体遮挡剔除。",
"CPU occlusion test runs this frame.": "本帧由 CPU 执行遮挡检测。",
"Occlusion checks run on a worker thread.": "遮挡检测在工作线程上运行。",
"Meshed sections uploaded per frame. Lower is smoother while loading.": "每帧上传的网格化区块数。越低加载时越流畅。",
"Soft shadows in corners. Costs chunk building time only.": "角落里的柔和阴影。只占用区块构建时间。",
"Smaller copies of block textures for distant terrain: less shimmer.": "为远处地形生成更小的方块纹理副本:减少闪烁。",
+1 -9
View File
@@ -10883,21 +10883,13 @@ impl Game<'_> {
self.res.block_entity_render().renders(*state)
&& (off_screen(*state) || in_view(p))
});
if self.entity_culler.is_some()
|| self.async_entity_culler.is_some()
|| self.pack_ids.is_some()
{
if self.pack_ids.is_some() {
for block in visible {
let start = out.len();
self.mark_block_entity(start, block.1);
self.res
.block_entity_render()
.render(&scene, std::iter::once(block), &mut out);
if !off_screen(block.1)
&& (self.entity_culler.is_some() || self.async_entity_culler.is_some())
{
self.cull_entity_vertices(&mut out, start);
}
}
} else {
self.res
@@ -298,7 +298,8 @@ impl Game<'_> {
/// drawn by no vanilla renderer) whose block entity is a mod's, closer than
/// `BlockEntityRenderer.getViewDistance` to the camera (`shouldRender`)
/// and with its bounds (`native_block_entity_render_bounding_box`) in the
/// frustum.
/// frustum. Entity occlusion culling is for ordinary entities; block
/// entities use these renderer-provided bounds instead.
pub(super) fn mod_block_entity_geometry<'a>(
&self,
blocks: impl Iterator<Item = &'a ([i32; 3], u32)>,
@@ -345,7 +346,6 @@ impl Game<'_> {
pos: (Vec3::from_array(v.pos) + origin).to_array(),
..*v
}));
self.cull_entity_vertices(&mut draw.vertices, start);
}
continue;
}
@@ -381,7 +381,6 @@ impl Game<'_> {
for v in &mut draw.vertices[start..] {
v.pos = (Vec3::from_array(v.pos) + origin).to_array();
}
self.cull_entity_vertices(&mut draw.vertices, start);
}
*out = draw.vertices;
}
+1 -1
View File
@@ -29,7 +29,7 @@ Every row has a one-line description and its cost in frame time (none, low, medi
`options.txt` keeps exactly vanilla's keys and values, so the options harness still compares it with vanilla; Horizon's settings live in `horizon-graphics.txt` beside it. Their defaults render as vanilla does: cave culling on, entity and leaf culling off, no upload budgets, sky, fog and weather on, 100% resolution, no anti-aliasing, HDR off, the present mode following VSync. VSync on always waits for the display (Fifo), in a window and in fullscreen, as in vanilla; the present mode setting chooses how frames are shown only while VSync is off. Frame pacing defaults to Efficient: the limiter sleeps through the last half millisecond where vanilla spins, which changes timing, not pixels.
**Entity Culling** is off by default and disabled with non-vanilla resource packs. Synchronous mode uses the existing same-frame CPU test. Asynchronous mode checks meshes on a worker and uses a result only when the camera and mesh bounds still match and the opaque chunks and rendered sections that proved occlusion are unchanged and ready. Until then, it leaves the mesh visible. Both modes leave simulation and interaction unchanged; older `entityCulling:true` settings select Synchronous.
**Entity Culling** is off by default and disabled with non-vanilla resource packs. It applies to entity models, not block entities, which retain their own frustum checks. Synchronous mode uses the existing same-frame CPU test. Asynchronous mode checks meshes on a worker and uses a result only when the camera and mesh bounds still match and the opaque chunks and rendered sections that proved occlusion are unchanged and ready. Until then, it leaves the mesh visible. Both modes leave simulation and interaction unchanged; older `entityCulling:true` settings select Synchronous.
**Battery mode** (Performance, off by default) is for laptops and handhelds: at most 60 frames per second in a world, 30 in menus without a world or while another window has focus, and half the automatic worker threads (chunks load slower). It changes only when frames are drawn: what they show and the game's 20 ticks per second stay as they are.