Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5003376e70 |
@@ -192,6 +192,8 @@ struct PendingSound {
|
||||
const SOUND_SPEED: f64 = 17.15;
|
||||
/// Past this the far variant plays: muffled, more rolling echo.
|
||||
const FAR: f64 = 140.0;
|
||||
/// The same when the game's acoustics muffle (its tracing reaches 512 blocks).
|
||||
const ACOUSTIC_FAR: f64 = 480.0;
|
||||
|
||||
/// Impulsive sounds (blasts, launches, shots, shock waves) come late from afar and have far variants.
|
||||
fn travels(event: &str) -> bool {
|
||||
@@ -747,13 +749,16 @@ impl AirDef {
|
||||
let now = self.sim.tick;
|
||||
// Blasts play layered (cinema.rs), the nearest ones in full.
|
||||
let mut booms: Vec<(f64, usize, DVec3, f32, f32)> = Vec::new();
|
||||
// The game muffles by walls and distance itself (#96): the near variants play out to the
|
||||
// reach of its tracing, so nothing is muffled twice; past it the far ones still do.
|
||||
let far = if render::acoustics() { ACOUSTIC_FAR } else { FAR };
|
||||
for (event, at, volume, pitch) in out.sounds {
|
||||
let dist = at.distance(self.listener);
|
||||
if let Some(power) = cinema::blast_power(event) {
|
||||
booms.push((dist, power, at, volume, pitch));
|
||||
} else if travels(event) {
|
||||
// Seen first, heard later; from afar muffled.
|
||||
let name = if dist > FAR { format!("{event}_far") } else { event.to_string() };
|
||||
let name = if dist > far { format!("{event}_far") } else { event.to_string() };
|
||||
let delay = (dist / SOUND_SPEED) as u64;
|
||||
if delay == 0 {
|
||||
render::play_sound(&name, at.x, at.y, at.z, volume, pitch);
|
||||
@@ -766,7 +771,7 @@ impl AirDef {
|
||||
}
|
||||
booms.sort_by(|a, b| a.0.total_cmp(&b.0));
|
||||
for (rank, (dist, power, at, volume, pitch)) in booms.into_iter().enumerate() {
|
||||
for l in cinema::layers(power, dist, FAR, volume, pitch, rank) {
|
||||
for l in cinema::layers(power, dist, far, volume, pitch, rank) {
|
||||
// Seen first, heard later: each voice after the sound has travelled.
|
||||
let delay = (dist / SOUND_SPEED) as u64 + l.delay;
|
||||
if delay == 0 {
|
||||
|
||||
@@ -11,6 +11,44 @@
|
||||
- Коммит из текста #96 (`76f680eb…`) в последних 200 коммитах `master` не нашёлся. Выводы привязаны к
|
||||
`453654ec`.
|
||||
|
||||
## Статус
|
||||
|
||||
**Стадия 1 (прямой звук) сделана**, включается `HORIZON_ACOUSTICS=1` (по умолчанию выключено, звук как был). Стадии 2-3
|
||||
не начаты. Коммит SPR прежний, `453654ec`; атрибуция: `horizon/crates/horizon-client/src/acoustics/THIRD_PARTY_SPR.md`.
|
||||
GPL-файл один: `acoustics/spr_occlusion.rs`; остальное (движок `acoustics.rs`, склейка `game/acoustics.rs`, DSP в `audio.rs`) наше.
|
||||
|
||||
Что вышло и чем отличается от плана выше:
|
||||
|
||||
- Фильтр голоса: не однополюсный lowpass, а **полка** (`audio::Occlusion`): ниже 1 кГц звук проходит с `gain`, выше с
|
||||
`gain * cutoff`, два полюса, сглаживание 80 мс на буфер. Однополюсник резал бы и басы толстой стены; нужно «глухо», а не «тихо».
|
||||
- Формулы SPR: `cutoff = exp(-occ*3)`, `gain = cutoff^0.1`, 9 путей со сдвигом 0.35 (для 16 самых громких; остальные 1 путь),
|
||||
блок источника не считается, неизвестный чанк = воздух, не полный блок x0.25. Луч — обход вокселей (свой), а не clip по формам:
|
||||
забор, дверь считаются ячейкой целиком (x0.25). Жидкости пока не глушат.
|
||||
- Дальность 512 блоков (SPR: ~64), счёт клеток, не времени: 40 тыс. клеток на тик встроенно (новый звук, 1 путь, чтобы взрыв
|
||||
не начинался «ярким»), 400 тыс. на задание рабочего потока (9 путей, одно задание за раз); при съёмке всё встроенно, 600 тыс.
|
||||
клеток на тик. Порядок: по громкости, затем по id; сумма голосов в `mix` теперь тоже по id (раньше порядок HashMap делал дорожку
|
||||
недетерминированной при нескольких голосах).
|
||||
- Кеш по ячейкам 2x2x2 источника и слушателя, 4096 записей; сброс по секциям `World.sound_changes` (как `mod_changes`),
|
||||
по эпохе мира и при переполнении; результат задания, начатого до изменения в его коробке, отбрасывается.
|
||||
- Воздух: `0.994^расстояние` на верха (EFX по умолчанию, не проверено по OpenAL Soft) — иначе при `acoustics=on` пропадала бы
|
||||
дальность, которую раньше давали `_far`-сэмплы.
|
||||
- Мод: API 21, `render.acoustics()`; при включённой акустике мод играет ближние варианты до 480 блоков (`ACOUSTIC_FAR`), дальше
|
||||
`_far`. Задержку распространения мод держит сам (не трогали).
|
||||
- Реплей: мир, из которого читает акустика, — тот самый `World`, где реплей показывает блоки на нужный момент (журнал
|
||||
изменений, `set-world-time-view`); перемотка пишет блоки через `put`/`set_block`, а они попадают в `sound_changes`. Значит
|
||||
стена, которой уже нет, в реплее не глушит, а которая была — глушит. Проверено чтением кода, не запуском.
|
||||
|
||||
Измерено (release, M-серия, `audio::tests::bench_one_hundred_voices_with_and_without_occlusion`, 100 голосов, буфер 512 кадров
|
||||
10.67 мс): 0.110 мс без акустики, 0.327 мс с полкой на всех (+0.217 мс, около 2% буфера); оценка 0.5-1 мс выше была завышена.
|
||||
|
||||
Проверка без слуха (`audio::tests::export_wall_tracks` через настоящие `Acoustics` и `mix`, затем `tools/acoustics_check.py`),
|
||||
выстрел 1.5 с на 60 блоках, стена камня в 2 блока: ниже 300 Гц -5.2 дБ (SPR: gain 0.55), 300-1500 -7.4, 1500-5000 -19.7, выше 5000 -40.0 дБ.
|
||||
Тесты: `cargo test -p horizon-client --lib acoustics` (формулы, неизвестное, щель, кеш, инвалидация, детерминизм, рабочий поток) и `audio`.
|
||||
|
||||
Не сделано / не проверено: запуск в игре и экспорт видео с настоящей сценой (склейка `game/acoustics.rs` — таблица состояний,
|
||||
снимок чанков — компилируется, но в игре не прогонялась); влияние на кадр при налёте; жидкости; дверь как проём (считается
|
||||
ячейкой); потолок памяти снимка. Стадии 2-3 (отводы эха, шины реверба) не начаты.
|
||||
|
||||
## 1. Как SPR идёт от источника к результату
|
||||
|
||||
Сигнал: Minecraft вызывает `Channel.play` → `mixin/SourceMixin.play` → `SoundPhysics.onPlaySound` →
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3de7a6875140a107e28563cc44489b55f5794517 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 12:37:45 +0300
|
||||
Subject: [PATCH 01/38] Mod API (AirDef fork): world models, client particles,
|
||||
Subject: [PATCH 01/39] Mod API (AirDef fork): world models, client particles,
|
||||
sounds, ground heights
|
||||
|
||||
render.set-models draws block models with an interpolated pose per id;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From a6d64e6415bf618539af464e521091e72b72d72f Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 12:39:45 +0300
|
||||
Subject: [PATCH 02/38] cargo-horizon-mod: report particles and sounds
|
||||
Subject: [PATCH 02/39] cargo-horizon-mod: report particles and sounds
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From ee79b3562feebe51959a01f1585a9e85bd53ccb5 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 13:33:10 +0300
|
||||
Subject: [PATCH 03/38] Mod API (AirDef fork): full-screen post pass for mods
|
||||
Subject: [PATCH 03/39] Mod API (AirDef fork): full-screen post pass for mods
|
||||
|
||||
render.set-post compiles a mod's WGSL after a prelude (camera matrices,
|
||||
time, 256 vec4 of params, the world's colour and depth) and runs it after
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 2b137dbbedd540daeebc7f5e387847aeb56a1355 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 22:09:30 +0300
|
||||
Subject: [PATCH 04/38] Mod models: draw far models as scaled impostors past
|
||||
Subject: [PATCH 04/39] Mod models: draw far models as scaled impostors past
|
||||
the far plane, cull at 4096
|
||||
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From c8ebca6e0af68630e65211844b34d25c5b985c03 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 22:31:00 +0300
|
||||
Subject: [PATCH 05/38] Mod cameras: render.set-views draws the world from
|
||||
Subject: [PATCH 05/39] Mod cameras: render.set-views draws the world from
|
||||
other points into pictures that HUD view shapes show (API level 9)
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8d2261fc4f8072c32e454139cfea7a8c0cd9d664 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 23:08:21 +0300
|
||||
Subject: [PATCH 06/38] Mods: more fuel per tick and per event (AirDef plans
|
||||
Subject: [PATCH 06/39] Mods: more fuel per tick and per event (AirDef plans
|
||||
raids)
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6c548de34def8e4a624d734243418090798bd16a Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Wed, 28 Oct 2026 23:25:29 +0300
|
||||
Subject: [PATCH 07/38] Mod cameras up to 1920x1080 (full-screen replays)
|
||||
Subject: [PATCH 07/39] Mod cameras up to 1920x1080 (full-screen replays)
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9b9e93269d67401cc620567a884d5ce97f68d76e Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 11:15:11 +0300
|
||||
Subject: [PATCH 08/38] Mod cameras: distant terrain tiles, fog measured from
|
||||
Subject: [PATCH 08/39] Mod cameras: distant terrain tiles, fog measured from
|
||||
the camera, no impostors while one is shown
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 065d9fa02966238a5bd9ff460392a1a809db0b11 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 11:25:45 +0300
|
||||
Subject: [PATCH 09/38] Mods: game.world-id, so mods keep state per world (API
|
||||
Subject: [PATCH 09/39] Mods: game.world-id, so mods keep state per world (API
|
||||
level 9)
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1bf28135fd9a31f837323dc3a8d81ed73343d816 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 12:01:08 +0300
|
||||
Subject: [PATCH 10/38] cargo-horizon-mod: trial runs behind feature full, so a
|
||||
Subject: [PATCH 10/39] cargo-horizon-mod: trial runs behind feature full, so a
|
||||
packing-only tool skips wasmtime
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0a56f5616df4699588cbcc529d4720661baa810f Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 13:18:43 +0300
|
||||
Subject: [PATCH 11/38] HD lighting: G-buffer pass, per-pixel mod point lights
|
||||
Subject: [PATCH 11/39] HD lighting: G-buffer pass, per-pixel mod point lights
|
||||
in HDR, bloom and tone curve; render.set-lights and render.set-lighting (API
|
||||
level 10)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9ebf0031fe9ba6b7f02afb26e4fd3a1ba4ddb0d0 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 13:59:43 +0300
|
||||
Subject: [PATCH 12/38] HD lighting stage 2: sun and moon shadow cascades, the
|
||||
Subject: [PATCH 12/39] HD lighting stage 2: sun and moon shadow cascades, the
|
||||
world relit (sun by face angle and shadow, sky and block light through the
|
||||
lightmap), light shafts and halos, fog over it again, a light colour grade
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 7a5a38f68923aec62f10bfa0df50b436474ed612 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 16:19:53 +0300
|
||||
Subject: [PATCH 13/38] HD: bind groups cached until a resize or a new source,
|
||||
Subject: [PATCH 13/39] HD: bind groups cached until a resize or a new source,
|
||||
shadow passes draw only the entities that cast shadows
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8020811e57d4b5a9ea1cd72d30ce859dc5095d35 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 16:25:44 +0300
|
||||
Subject: [PATCH 14/38] HD: lights culled per 16x16 tile (surface and halo
|
||||
Subject: [PATCH 14/39] HD: lights culled per 16x16 tile (surface and halo
|
||||
lists built on the CPU), a naga test for the lighting shaders
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 72d3fddfea329e578162656151350f0aa2efd323 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 16:43:36 +0300
|
||||
Subject: [PATCH 15/38] HD: GPU time per pass in the F3 timing list,
|
||||
Subject: [PATCH 15/39] HD: GPU time per pass in the F3 timing list,
|
||||
half-resolution GTAO with a depth-aware blur
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1fd83a821bf270879d8ece5aa583f200ed920d89 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 17:02:02 +0300
|
||||
Subject: [PATCH 16/38] HD: shadows draw only sun-facing quads and skip buried
|
||||
Subject: [PATCH 16/39] HD: shadows draw only sun-facing quads and skip buried
|
||||
sections, the far cascade every second frame; TAA (Halton jitter,
|
||||
reprojection by depth, YCoCg variance clipping) before bloom
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1502d359d599228fe0f44ce6b99a3fded2ac5ea0 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 17:02:02 +0300
|
||||
Subject: [PATCH 17/38] Mods: model handles (render.model-id, model-generation,
|
||||
Subject: [PATCH 17/39] Mods: model handles (render.model-id, model-generation,
|
||||
set-models-by-id; API level 11) so mods send no model names each tick;
|
||||
clear-post and set-lighting documented
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0f9d99b8ad3e4b72e621d84c2396cf1d3d2b7a33 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 17:19:57 +0300
|
||||
Subject: [PATCH 18/38] HD: temporal upscaling (HORIZON_HD_SCALE: world,
|
||||
Subject: [PATCH 18/39] HD: temporal upscaling (HORIZON_HD_SCALE: world,
|
||||
G-buffer and lighting at a lower size, rebuilt to the window in the TAA
|
||||
pass); fix flickering shadows near the player (the near cascade lost its
|
||||
sections on frames the far one was held, the held far matrix ignored the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 38250c4392e27d5700842ca6ee47291dd1831b72 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 17:47:52 +0300
|
||||
Subject: [PATCH 19/38] HD water: its own pass (colour, normal, depth), the
|
||||
Subject: [PATCH 19/39] HD water: its own pass (colour, normal, depth), the
|
||||
floor under it lit, a composite with world-space waves, refraction with depth
|
||||
absorption in the biome colour, screen-space reflections, Fresnel and a
|
||||
shadowed sun glint (HORIZON_HD_WATER=0 to switch off)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From dbc6f8a6e9c2eeabe1de15f1794013c90be7faa5 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 17:56:04 +0300
|
||||
Subject: [PATCH 20/38] HD water: no vanilla texture on the surface (the biome
|
||||
Subject: [PATCH 20/39] HD water: no vanilla texture on the surface (the biome
|
||||
colour only), a darker, deeper colour
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 13e74537dd6e63482e3613e0e416de1158944dfe Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 18:38:19 +0300
|
||||
Subject: [PATCH 21/38] HD sky and light: a physical atmosphere (Rayleigh, Mie,
|
||||
Subject: [PATCH 21/39] HD sky and light: a physical atmosphere (Rayleigh, Mie,
|
||||
ozone; constants and transmittance after Photon, MIT) for the sky, haze, fog
|
||||
and water reflections; warmer sunlight from the atmosphere's transmittance, a
|
||||
gentle sky-coloured ambient, soft PCSS-lite shadows near the player, a haze
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6277e051a89c2537570982f6ef275887193c05cf Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 19:02:16 +0300
|
||||
Subject: [PATCH 22/38] HD water: a darker blue, a little clearer, ripples a
|
||||
Subject: [PATCH 22/39] HD water: a darker blue, a little clearer, ripples a
|
||||
little higher
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 982265d21bb9d74ec0040db03feb5a55762286ad Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 21:41:48 +0300
|
||||
Subject: [PATCH 23/38] HD: Photon-style sunsets (Rec. 2020 atmosphere, sun
|
||||
Subject: [PATCH 23/39] HD: Photon-style sunsets (Rec. 2020 atmosphere, sun
|
||||
tint, blue hour; MIT), volumetric clouds with ground shadows instead of
|
||||
vanilla's in HD, volumetric fog with sun shafts and morning mist
|
||||
(HORIZON_HD_CLOUDS=0, HORIZON_HD_VOLFOG=0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 24971b3c67d8c87673eb2e0d204cedf8a2f46d1c Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 21:43:22 +0300
|
||||
Subject: [PATCH 24/38] Mods: world queries for simulations (render.query-rays,
|
||||
Subject: [PATCH 24/39] Mods: world queries for simulations (render.query-rays,
|
||||
query-sections, world-changes; API level 12): block-exact rays and section
|
||||
occupancy by collision, sight or sound, answered next tick within budgets,
|
||||
and a log of changed sections
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From fdec4960983bdff82f3793460f9a5234f0cd3f49 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 22:56:15 +0300
|
||||
Subject: [PATCH 25/38] HD fixes: rain level from the world not from rain
|
||||
Subject: [PATCH 25/39] HD fixes: rain level from the world not from rain
|
||||
geometry (#41), TAA history on the jittered grid (#38), vanilla cloud tint
|
||||
without a depth heuristic (#35), air fog once over water (#37), translucent
|
||||
things in front of HD water (#36), cheaper sunrise fan (#39), halos in thick
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 21391afb26f49505d6cdaf454a6355cd4e747503 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 23:19:53 +0300
|
||||
Subject: [PATCH 26/38] HD split into modules (gfx/hd/: one Rust file and one
|
||||
Subject: [PATCH 26/39] HD split into modules (gfx/hd/: one Rust file and one
|
||||
WGSL file per pass, a shared prelude), contracts for colour, depth, alpha,
|
||||
time and coordinates written down, tests that the frame layout and bindings
|
||||
match between Rust and WGSL (#45)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8d4cadbf8534309ac847d34e229f6d764770475d Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Thu, 29 Oct 2026 23:22:19 +0300
|
||||
Subject: [PATCH 27/38] HD clouds: noise scales that divide the camera's
|
||||
Subject: [PATCH 27/39] HD clouds: noise scales that divide the camera's
|
||||
65536-block wrap, so the clouds and their shadows no longer jump at x or z =
|
||||
0
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0fb59c782abf269fe555faa3241b31acf41e26d7 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 03:17:11 +0300
|
||||
Subject: [PATCH 28/38] HD: volumetric smoke and missile trails with clear
|
||||
Subject: [PATCH 28/39] HD: volumetric smoke and missile trails with clear
|
||||
tunnels through fog and cloud (render.set-smoke, API level 14; #54); sun
|
||||
speculars by material, wet surfaces and puddles in rain, wind in foliage
|
||||
(HORIZON_HD_SPECULAR=0, HORIZON_HD_WIND=0, HORIZON_HD_SMOKE=0); HD shaders
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From e4bc29da45d0d38244c6eb2ba3ffb9ab853540c0 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 03:26:09 +0300
|
||||
Subject: [PATCH 29/38] HD clouds composited by depth so terrain and vehicles
|
||||
Subject: [PATCH 29/39] HD clouds composited by depth so terrain and vehicles
|
||||
inside or behind the layer are hidden and those in front stay in front (#67);
|
||||
world-anchored noise everywhere (cloud detail by height above the layer, fog,
|
||||
smoke and puddle scales dividing the wrap) (#68); the replay's time is visual
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 20f699796afb12b600236a4e8859cd97430f86f0 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 03:44:45 +0300
|
||||
Subject: [PATCH 30/38] HD smoke: young trails drawn at least as wide as a grid
|
||||
Subject: [PATCH 30/39] HD smoke: young trails drawn at least as wide as a grid
|
||||
cell (density scaled to keep the mass), gentler bulges, so a trail is a
|
||||
smooth ribbon and not a chain of puffs
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 35ffbaa26dd91855c8b93446646ba8c58448d3d0 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 03:59:41 +0300
|
||||
Subject: [PATCH 31/38] Mods: render.set-main-view (API level 15) renders the
|
||||
Subject: [PATCH 31/39] Mods: render.set-main-view (API level 15) renders the
|
||||
screen's world from a mod camera with the full pipeline, so replays get HD
|
||||
and the post effects; small mod views get the post pass with their own camera
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 27e24527550942695164dd3a769a42a659e797ca Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 09:28:05 +0300
|
||||
Subject: [PATCH 32/38] Spot lights for mods (render.set-spot-lights, API level
|
||||
Subject: [PATCH 32/39] Spot lights for mods (render.set-spot-lights, API level
|
||||
16): surfaces lit in the cone, a volumetric beam stopped by depth (#60); film
|
||||
capture (render.capture-*, set-film-quality, API level 17): fixed-step clock,
|
||||
frames piped to ffmpeg or PNGs, offline audio, no chat in the frames (#58);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 615f5c3fa7c19a9895f8972a88333c6f250ad78a Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 14:30:39 +0300
|
||||
Subject: [PATCH 33/38] HD clouds and fog polish: cloud panorama, cirrus,
|
||||
Subject: [PATCH 33/39] HD clouds and fog polish: cloud panorama, cirrus,
|
||||
terrain-aware fog, far smoke cascade; replay world log and film clock;
|
||||
material overlays by sprite name
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0254984fdcce53a4a0f2bff15f9be3b78c93842e Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 15:01:09 +0300
|
||||
Subject: [PATCH 34/38] HD: coloured sun through glass and leaves, rain ripples
|
||||
Subject: [PATCH 34/39] HD: coloured sun through glass and leaves, rain ripples
|
||||
on water, film motion blur and depth of field
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9645d3f1f47d8bb358d5630288bdd801bd874911 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 15:19:32 +0300
|
||||
Subject: [PATCH 35/38] Film export: every frame in flight reaches the writer,
|
||||
Subject: [PATCH 35/39] Film export: every frame in flight reaches the writer,
|
||||
listener follows the main view, cloud wind on film frames, set-smoke reports
|
||||
real activity
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 22d6835507d5627b0fe4a749b082b025b35e0262 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 15:43:11 +0300
|
||||
Subject: [PATCH 36/38] Mod command trees: command.set-tree and
|
||||
Subject: [PATCH 36/39] Mod command trees: command.set-tree and
|
||||
set-suggestions, typed parse, colouring and completion from one tree (API 19)
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9be21a54fff055e78db245488c28a971a823fdba Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 16:10:23 +0300
|
||||
Subject: [PATCH 37/38] Persistent mod sound sources: start, update, stop with
|
||||
Subject: [PATCH 37/39] Persistent mod sound sources: start, update, stop with
|
||||
generations, click-free voices, loop sections, voice budget and virtual loops
|
||||
(API 20)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From e84cdc21a9fabc4518c18edbeacb2df24c85b983 Mon Sep 17 00:00:00 2001
|
||||
From: chexit <chexit@duck.com>
|
||||
Date: Fri, 30 Oct 2026 19:07:37 +0300
|
||||
Subject: [PATCH 38/38] HD clouds: rays from a far point, so the view bob's eye
|
||||
Subject: [PATCH 38/39] HD clouds: rays from a far point, so the view bob's eye
|
||||
offset does not bend them
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Проверка акустики без слуха (#96): энергия по полосам в дорожке с преградой и без неё.
|
||||
|
||||
python3 tools/acoustics_check.py open.raw wall.raw # s16le, 48000 Гц, стерео
|
||||
python3 tools/acoustics_check.py open.raw wall.raw --rate 48000 --channels 2
|
||||
|
||||
Дорожки берутся из `Audio::film_mix` (экспорт видео пишет `<имя>.audio.raw`) или из теста
|
||||
`cargo test -p horizon-client --lib audio::tests::export_wall_tracks -- --ignored` (HORIZON_ACOUSTICS_OUT=папка).
|
||||
Для каждой дорожки считается энергия левого канала в четырёх полосах (до 300 Гц, 300-1500, 1500-5000, выше
|
||||
5000) и разница в дБ между дорожками. Преграда должна срезать верхи (выше 5 кГц не меньше чем на 15 дБ) и
|
||||
оставить низы (до 300 Гц теряют не больше 8 дБ). Коды выхода: 0 — в порогах, 1 — нет, 2 — ошибка аргументов.
|
||||
Только стандартная библиотека.
|
||||
"""
|
||||
import argparse
|
||||
import array
|
||||
import cmath
|
||||
import math
|
||||
import sys
|
||||
|
||||
BANDS = [("<300", 0, 300), ("300-1500", 300, 1500), ("1500-5000", 1500, 5000), (">5000", 5000, 1e9)]
|
||||
|
||||
|
||||
def fft(a):
|
||||
n = len(a)
|
||||
if n == 1:
|
||||
return a
|
||||
even, odd = fft(a[0::2]), fft(a[1::2])
|
||||
t = [cmath.exp(-2j * math.pi * k / n) * odd[k] for k in range(n // 2)]
|
||||
return [even[k] + t[k] for k in range(n // 2)] + [even[k] - t[k] for k in range(n // 2)]
|
||||
|
||||
|
||||
def bands(path, rate, channels):
|
||||
raw = array.array("h")
|
||||
with open(path, "rb") as f:
|
||||
data = f.read()
|
||||
raw.frombytes(data[: len(data) // 2 * 2])
|
||||
left = [s / 32768.0 for s in raw[0::channels]]
|
||||
n = 1
|
||||
while n * 2 <= len(left):
|
||||
n *= 2
|
||||
n = min(n, 1 << 16)
|
||||
if n < 1024:
|
||||
sys.exit(f"{path}: too short ({len(left)} frames)")
|
||||
# A Hann window over the loudest n frames' start: the burst is at the start of the track.
|
||||
w = [left[i] * (0.5 - 0.5 * math.cos(2 * math.pi * i / (n - 1))) for i in range(n)]
|
||||
spec = fft([complex(v) for v in w])
|
||||
out = [0.0] * len(BANDS)
|
||||
for k in range(1, n // 2):
|
||||
hz = k * rate / n
|
||||
for i, (_, lo, hi) in enumerate(BANDS):
|
||||
if lo <= hz < hi:
|
||||
out[i] += abs(spec[k]) ** 2
|
||||
return out
|
||||
|
||||
|
||||
def db(a, b):
|
||||
return 10 * math.log10(max(a, 1e-20) / max(b, 1e-20))
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__.split("\n")[0])
|
||||
p.add_argument("open")
|
||||
p.add_argument("wall")
|
||||
p.add_argument("--rate", type=int, default=48000)
|
||||
p.add_argument("--channels", type=int, default=2)
|
||||
p.add_argument("--min-high-cut", type=float, default=15.0, help="dB the band above 5 kHz must drop")
|
||||
p.add_argument("--max-low-loss", type=float, default=8.0, help="dB the band below 300 Hz may drop")
|
||||
a = p.parse_args()
|
||||
o, w = bands(a.open, a.rate, a.channels), bands(a.wall, a.rate, a.channels)
|
||||
print(f"{'band, Hz':>10} {'open dB':>9} {'wall dB':>9} {'change dB':>10}")
|
||||
ref = max(o)
|
||||
for (name, _, _), x, y in zip(BANDS, o, w):
|
||||
print(f"{name:>10} {db(x, ref):9.1f} {db(y, ref):9.1f} {db(y, x):10.1f}")
|
||||
low, high = db(w[0], o[0]), db(w[-1], o[-1])
|
||||
ok = high <= -a.min_high_cut and low >= -a.max_low_loss
|
||||
print(f"highs {high:.1f} dB (need <= -{a.min_high_cut}), lows {low:.1f} dB (need >= -{a.max_low_loss}): {'ok' if ok else 'FAIL'}")
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user