Звездошиза · шаблон

Кася: Live2D + бесшовные видеовставки

Основа — Live2D-модель. Отдельные эмоции проигрываются коротким клипом из Grok Imagine и бесшовно возвращаются обратно в Live2D.

Основной сайт

Кася готовится…

Live2D

Хронология перехода

Нажми «▶ Злость», чтобы увидеть фазы.

    Как это работает

    Переход Live2D → видео → Live2D

    1. Предзагрузка. Каждый клип из реестра (js/clips.js) заранее грузится в скрытый <video>, декодируется и стоит на паузе на кадре 0.
    2. Нейтраль. По команде модель останавливает движения и выражения и за ~0,45 с плавно сводит все параметры к нейтральной позе (позе первого кадра клипа), физика волос успокаивается.
    3. Кадр 0. Кадр 0 клипа заливается в WebGL-слой поверх модели; ждём, что он действительно отрисован (requestVideoFrameCallback, где есть).
    4. Подмена. Кроссфейд 100–200 мс (или жёсткая склейка), Live2D скрывается и перестаёт рендериться, видео запускается.
    5. Возврат. За ~160 мс до конца клипа Live2D включается под видео уже в той же нейтральной позе, видео гаснет, затем поза отпускается и снова идёт Idle.
    6. Очередь. Если Кася говорит (липсинк) или уже идёт клип, новый клип ждёт в очереди. Звук клипа можно оставить или выключить.

    Требования к клипам из Grok Imagine

    • Стартовая картинка = нейтральный кадр модели. Нажми «Скачать нейтральный кадр» и генерируй клип из этой картинки. Тогда первый кадр клипа совпадёт с Live2D.
    • Последний кадр = первый. В подсказке проси: «в конце вернуться в исходную позу, неподвижно». Если конец не совпал, обрежь хвост или сделай мягкий кроссфейд подлиннее.
    • Тот же ракурс и разрешение. Без движения камеры и зума; все клипы одной сцены — одно разрешение (сейчас 1168×784).
    • Фон — сплошной зелёный (или чёрный). Для чистого вырезания генерируй на ровном зелёном #00B140 (нет зелёного в костюме Каси) и используй режим «Хромакей». Чёрный фон годится для «тёмного ключа», но тёмная шляпа и платье тоже станут полупрозрачными.
    • Формат. MP4 H.264 с faststart (+ WebM как запасной). Пример: ffmpeg -i in.mp4 -c:v libx264 -crf 20 -pix_fmt yuv420p -movflags +faststart -c:a aac out.mp4.

    Фон: два режима

    • Видео целиком (по умолчанию). Клип закрывает всю сцену вместе со своим запечённым фоном. Чтобы шва не было, фон сцены во время Live2D — «чистая подложка», вырезанная из кадра 0 клипа (ровный фон #090512 + стол без персонажа). Цвет фона клипа почти совпадает с фоном сайта (#0c0714), поэтому всё выглядит единым.
    • Фон сайта + вырезание. Видео проходит через WebGL-шейдер: хромакей (цвет, допуск, мягкость, подавление ореола) или тёмный ключ, и ложится поверх звёздного фона сайта. Стол из клипа шире стола модели, поэтому под звёздами показывается полоса стола из подложки, а у модели остаётся только шар с подставкой — стол один в обоих состояниях. На текущем клипе (почти чёрный фон, красное свечение) тёмный ключ работает прилично: свечение и тёмная одежда сохраняются, но тёмные полупрозрачные края и дымка свечения ложатся на фон чуть грязнее, чем при хромакее. Для этого режима лучше генерировать клипы на зелёном.

    Как добавить клип

    { id: "laugh", label: "Хохот",
      sources: [{ src: "clips/laugh.mp4", type: "video/mp4" }],
      triggerEmotion: "Smile", chance: 0.3,
      audio: true, poseParams: {}, endLeadMs: 160 }

    Положи файл в clips/ и допиши объект в ZV_CLIPS. triggerEmotion — эмоция с бэкенда, при которой вместо выражения Live2D иногда (с вероятностью chance) играет клип.