V01. Свой конфиг растительности и травинки вблизи (рекомендации 1, 3, 4)

Цель: трава у земли дешевле вдали, приминается только ногами, посадки скошены прямоугольником, сухость по локации; настройки растительности — в своём файле, чтобы группа не делила configs/world.json с рельефом.

Контекст: docs/plan/README.md (группа 5, «Рекомендации для GrassField»), docs/guide/terrain.md («Ветер на земле», травинки), scripts/terrain/grass_field.gd, grass.gdshader, terrain.gd (_make_grass, trees_cfg), docs/guide/world-objects.md (get_landing_sites). Владения: configs/vegetation.json (новый), configs/world.json (только удалить разделы grass, trees), scripts/terrain/{grass_field.gd, grass.gdshader, terrain.gd} (в terrain.gd — только чтение конфига и вызовы травы), tests/vegetation/ (новая), docs/guide/vegetation.md (новый), docs/guide/terrain.md (таблица файлов → ссылка на vegetation.md).

Шаги

  1. Перенести разделы grass и trees в configs/vegetation.json (слияние с переопределениями локации сохранить); кадры до/после идентичны.
  2. Прореживание: пучку — rank 0..1 (хеш), виден при rank < плотность(расстояние); дальние шире (far_width_k).
  3. Приминание гасить по высоте ног над землёй: полное ≤ 0,4 м, ноль ≥ 1,2 м; нормаль травинки явно, без переворота (cull_disabled).
  4. Посадки — прямоугольник (axis_deg, length_m, width_m): GrassField.set_landing_sites(sites); вызов из WorldObjects.get_landing_sites() подключает группа «Сцена игры» (до того — круги по Terrain.get_landing_sites).
  5. Сухость травинок по локации поверх палитры (vegetation.json → grass.dryness_add: Онгудай +0,35, Аскарово +0,25).
  6. docs/guide/vegetation.md: файлы, API, параметры, замеры.

Критерий приёмки

  • Шаг 1: кадры S1, S2 стенда T01 (пока стенд не готов — те же ракурсы через --shot) до/после переноса — PSNR ≥ 45 дБ; тесты tests/terrain зелёные.
  • Тест: вершин травы в кольце 20–30 м в 5–8 раз меньше, чем в 0–10 м на единицу площади.
  • Тест: пилот в 1,5 м над землёй — приминание 0; на земле — полное. Точка в прямоугольнике посадки — скошено, в 1 м за краем — нет.
  • S1 против солнца (yaw +180): обратные стороны травинок не темнее лицевых > 15 % (средняя яркость полосы травы).
  • GPU травы (S1: с травой − --no-grass) ≤ 0,3 мс (было ~0,5).

Зависимости: нет (волна 0, параллельно T01). Модель: sonnet. Размер: M.