Как это работает
Переход Live2D → видео → Live2D
- Предзагрузка. Каждый клип из реестра (
js/clips.js) заранее грузится в скрытый<video>, декодируется и стоит на паузе на кадре 0. - Нейтраль. По команде модель останавливает движения и выражения и за ~0,45 с плавно сводит все параметры к нейтральной позе (позе первого кадра клипа), физика волос успокаивается.
- Кадр 0. Кадр 0 клипа заливается в WebGL-слой поверх модели; ждём, что он действительно отрисован (
requestVideoFrameCallback, где есть). - Подмена. Кроссфейд 100–200 мс (или жёсткая склейка), Live2D скрывается и перестаёт рендериться, видео запускается.
- Возврат. За ~160 мс до конца клипа Live2D включается под видео уже в той же нейтральной позе, видео гаснет, затем поза отпускается и снова идёт Idle.
- Очередь. Если Кася говорит (липсинк) или уже идёт клип, новый клип ждёт в очереди. Звук клипа можно оставить или выключить.
Требования к клипам из 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) играет клип.