| 2026-09-12 |
Фиксы ревью движка: параллакс тумана, dispose молнии, tint при росте слоя
...
- fog: дрейф слоёв теперь убывает с глубиной (0.42−0.05·k) — код
противоречил доку «глубокие слои медленнее» (параллакс объёма).
- lightning: dispose посреди вспышки гасит свет рендера и слой —
раньше DirectionalLight и env-подсветка дождя замирали навсегда.
- particles: обёртка слоя помнит tint и переапплаит его свежему impl
при росте ёмкости (иначе новый меш получал дефолтный белый).
- тесты: dispose молнии гасит свет; tint переживает рост (спрайты/квады).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
9 hours ago
|

Многослойный туман по дальности от камеры + слайдер дев-панели
...
Композитный проход: сцена → RT с DepthTexture, полноэкранный квад
реконструирует мировую точку (в орто глубина линейна) и красит кадр
стопкой из 6 слоёв по дистанции вдоль взгляда ОТ КАМЕРЫ. Клубы — fbm
по мировым XZ с дрейфом ветра (глубокие слои медленнее — параллакс),
высотное затухание собирает туман в низинах; цвет — env-свет сцены
(день светло-серый, ночь тёмный). Полоты ⟂ оси взгляда забракованы
пробой-изолятом: при взгляде ~63° плоскости уходят под рельеф.
Главная грабля: d в шейдере обязан быть dot(wp − uCamPos, uCamF) —
глубиной от КАМЕРЫ; вариант от цели давал для видимых пикселей
d ∈ [−1.12·V, +1.12·V] при слоях на 2.5..5·V — все smoothstep'ы
нули, туман полностью прозрачен (изолят маскировал: камера ближе).
Попутно чинит pow-граблю из 55876f8: степень PARTICLE_LIT_GAMMA из TS
в GLSL-шаблоне печаталась «2» (int) — pow(int) не компилировался в
GLSL ES, lit-слои частиц (дождь/снег/пепел/листья/пыль) молча не
рисовали; в GLSL-шаблоны числа из TS — через .toFixed(1).
WeatherSpec.fog (0..1), база прудов 0.3; 6-й слайдер «туман» в дев-
панели. Гейт weather: 19 проверок (+6 туман: рисуется, глубинный
градиент, дрейф, ночь тёмная, слайдер панели). check:fast — 377 ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
12 hours ago
|

Освещаемые частицы в темноте ещё темнее: квадрат видимости + гашение цвета
...
Фидбек: «освещаемые партиклы в темноте сделаем ещё темнее». Две правки
ветки #if LIT шейдера частиц:
1) vis гасит и цвет, и альфу: vColor*(uTint*vis + received) — раньше
гасилась только альфа, цвет оставался полным, и полупрозрачные СЕРЫЕ
точки читались на тёмном фоне;
2) кривая видимости нелинейная: vis = clamp((max-канал(received)*1.6)^2) —
степень давит слабый свет (ночь received ~0.05-0.1: линейная кривая
оставляла vis ~0.1), а день/лампа по-прежнему насыщают vis в 1.
Чистая функция litVisibility(maxChannel) зеркалит шейдерную кривую —
тесты без WebGL (371). Замер пробы (пара кадров ночью «дождь вкл/выкл»,
пиксели ярче фона): 815 -> 641 (гашение цвета) -> 10 (квадрат); день
не изменился (дождь 101 -> 100), мотыльки (излучающие) светятся как
раньше (961 тёплых px).
Гейт weather «облачность темнит кадр» ослаблен до x0.93: зенитный свет
пасмурного дня (fd7a331) намеренно добавляет освещённости — падал и до
этой правки (воспроизведено на старом шейдере, цифры те же).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
12 hours ago
|

Два вида частиц: излучающие и освещаемые сценой (lit)
...
Живучий баг «частицы светятся одинаково при любом освещении»: теперь
режим — свойство слоя. renderer.addParticles({lit: true}) — освещаемый
слой: полученный свет (env-свет сцены + точечные источники) правит и
цветом, и видимостью (альфа = clamp(max-канал·PARTICLE_LIT_VIS)) — ночью
в темноте частица исчезает, у лампы/фонарика проявляется, днём вид как
раньше. Излучающий режим (по умолчанию) — прежняя формула.
- particleEnv(amb, sun) — чистая функция env-света (ambient + доля
солнца PARTICLE_ENV_SUN 0.3: у билборда нет нормали); рендер
пересчитывает uEnv в конце setSun — туда сходятся все изменения света;
- игра: lit — дождь/снег (WeatherSystem.setTint удалён), пепел,
листья/пыль; tint остался самосветящимся: мотыльки, дымка, блики.
Ручной ночной tint был подменой реакции на свет — больше не нужен.
Замер в игре: дождь день 101 / ночь 14 яркости, в луче фонарика капли
проявляются; мотыльки ночью светятся как раньше. Тесты 368 ✓ (+particleEnv),
гейты atmosphere/weather/panels ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Свет частиц читается: a² вместо a³ + конус фонарика 2.2× для объёма
...
Диагноз: реакции частиц на свет были перцептивно нулевыми при исправной
проводке. Точечные источники: кубический фоллофф концентрировал вклад в
внутреннем ~10% радиуса (среднее a³ по сфере ≈ 1/60) — изолят с игровыми
условиями давал +1.4% яркости. Фонарик: тонкий горизонтальный луч едва
пересекает видимый ортокамерой слой — ~20 капель (76 px diff), глаз не
ловил; подтверждено хирургическим A/B в живой игре (flip uSpotOn при
замороженном времени).
Фикс: квадратичный фоллофф точечных источников в LIGHT_FRAG (капли в
пятне лампы тёплые и яркие), конус спота для частиц в 2.2× шире
поверхностного с клампом полуугла (луч читается светящейся цепочкой
капель). Гейт atmosphere/weather ✓, check:fast — 353 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 hours ago
|
Фикс #218: рост ёмкости слоя частиц не плодит замороженные меши
...
Редирект layer.update = fresh.update при росте ёмкости ломался, когда
держатель слоя (WeatherSystem) снял методы заранее: ссылка навсегда
указывала в замыкание старой реализации, каждый тик сверх ёмкости
создавал новый слой с однократной записью — замороженные снимки дождя
копились в сцене (пелена на весь экран, ~46 слоёв).
Теперь createSpriteLayer/createQuadLayer держат стабильный фасад:
публичный объект один на всю жизнь слоя, при росте подменяется только
внутренняя реализация, первый кадр после роста рисуется сразу.
Регрессия particleLayers.test.ts (метод снят заранее — меш один).
Живой прогон: veil% 3.6→13.5 (накопление) → стабильные 0.07-0.09.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
16 hours ago
|
Свет частиц: точечные источники и фонарик подсвечивают слои частиц
...
- Движок: общий блок юниформ света на рендере (packParticleLights,
setParticleLights), шарится ссылками между слоями; шейдерный вклад
ламп/конуса умножается на цвет частицы, ×2 на согласование с GAIN-пулами.
- Игра: GameLighting отдаёт снапшот источников + конус фонарика каждый тик;
снапшот моста — lightingInfo.particleLights.
- Гейт atmosphere +2 (день 0 / ночь = источникам), 332 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|
Озёра утоплены, деревья крупнее, манекен 8×12×4, теневой фрустум по кадру, частицы в системе освещения
...
- Вода: яма y=1 пуст / вода y=0; непроходимость — physicsWorld
(невидимый коллайдер над ямами); декор на воде не штампуется.
- Деревья: стволы 25-38, кроны 17-24, чанк 64.
- Манекен 8×12×4 (134 вокс, 19 тайлей — детализация на текстурах),
снаряжение пропорционально меньше (рюкзак 40 / факел 4 / фонарик 16).
- Тени: динамический фрустум в setSun (visible·aspect + высота кастера),
mapSize 2048 — граница включения теней больше не видна.
- Частицы: uTint в ParticleLayer, ночной тинт PARTICLE_NIGHT,
размеры уменьшены (пепел/листья/пыль/дымка/мотыльки).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|
| 2026-09-11 |

Слой частиц движка: спрайты/плоские квады + окно видимости камеры
...
Частицы больше не воксели: отдельный 2D-слой поверх мира (THREE.Points
билборды и InstancedBufferGeometry квады в XZ), без освещения и теней.
Окно видимости частиц — точный AABB сляба ортокамеры на слое [y0,y1]
(polyWindow, перебор вершин полиэдра). Пепел/мотыльки/дымка/блики воды
переведены на слой: частицы живут в мировых координатах, окно камеры
заворачивает их с маржой за экран, в марже альфа гаснет — без появления
из воздуха. Окно покрывает весь кадр с перекрытием.
Движок: particles.ts (ParticlePoint/ParticleLayer, createSpriteLayer/
createQuadLayer, addParticles/addFlatParticles), polyWindow.ts,
visibleWindow(y0,y1), 4 теста (симметрия следа, покрытие окна,
сдвиг от высоты, вырожденность). Игра: particlesWindow.ts (маржа,
wrap, edgeAlpha), миграция ash/ambientParticles/waterShimmer,
setAsh пересобирает частицы области.
Грабли: знаки полуплоскостей n·δ≤b; AABB в дельтах — прибавлять target;
окно без кэша (едет за камерой); квады на воде — над гранью y=3;
fresh.update после роста ёмкости; скорости по v1 (px/s ÷ 32).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|