diff --git a/client/src/characters.js b/client/src/characters.js new file mode 100644 index 0000000..ed3d959 --- /dev/null +++ b/client/src/characters.js @@ -0,0 +1,91 @@ +// 8 個 AI 品牌擬人角色設定(佔位版) +// 資料來源:docs/角色視覺映射筆記.md +// 注意:目前用品牌色 + 性格做 CSS/SVG 佔位;正式立繪待 ComfyUI 生成後以 替換。 + +export const CHARACTERS = [ + { + id: 'grok4', + name: 'Grok-4', + brand: '粉紅', + color: '#ff7eb6', + hair: '#f28d3f', + desc: '超絕演技、情緒型玩家、拿好牌演苦情戲', + trait: '演戲', + emoji: '🎭' + }, + { + id: 'kimi', + name: 'Kimi', + brand: '深藍', + color: '#3b5bdb', + hair: '#d9e2ff', + desc: '原始直覺強、相對踏實的老派', + trait: '老派', + emoji: '🤔' + }, + { + id: 'qwen3', + name: 'Qwen3', + brand: '藍紫', + color: '#845ef7', + hair: '#f7a8c8', + desc: '踏實、質疑比例極高、十足刺兒頭', + trait: '刺兒頭', + emoji: '🔍' + }, + { + id: 'gpt5', + name: 'GPT-5', + brand: '黑', + color: '#495057', + hair: '#212529', + desc: '老謀深算、心理戰高手、想足', + trait: '沉穩', + emoji: '🧠' + }, + { + id: 'gemini', + name: 'Gemini', + brand: '淺紫', + color: '#b197fc', + hair: '#b384f7', + desc: '活潑好奇、容易亂、總先被淘汰', + trait: '好奇', + emoji: '✨' + }, + { + id: 'deepseek', + name: 'Deepseek', + brand: '藍', + color: '#339af0', + hair: '#74c0fc', + desc: '面無表情、侵略如火、戲劇化表演', + trait: '瘋癲', + emoji: '🎲' + }, + { + id: 'doubao', + name: 'Doubao', + brand: '淺藍', + color: '#66d9e8', + hair: '#8b5a2b', + desc: '乾淨利落、反情緒、獵殺時刻', + trait: '冷靜', + emoji: '🎯' + }, + { + id: 'claude', + name: 'Claude', + brand: '橘', + color: '#ffa94d', + hair: '#ff922b', + desc: '溫和堅定、雲淡風輕、嘴角微揚', + trait: '淡定', + emoji: '🍵' + } +] + +// 依 player 索引分配角色(讓每個座位有固定 Q 版角色) +export function characterFor(index) { + return CHARACTERS[index % CHARACTERS.length] +} diff --git a/client/src/components/GameTable.vue b/client/src/components/GameTable.vue index 74a4b24..c955f66 100644 --- a/client/src/components/GameTable.vue +++ b/client/src/components/GameTable.vue @@ -1,151 +1,129 @@ @@ -153,15 +131,16 @@ import { ref, computed, watch } from 'vue' import { useGameStore } from '../stores/game' import { storeToRefs } from 'pinia' -import { - NCard, NSpace, NList, NListItem, NAvatar, NTag, - NDescriptions, NDescriptionsItem, NButton, NH3, NText, NAlert -} from 'naive-ui' +import { NButton } from 'naive-ui' +import PlayerSeat from './PlayerSeat.vue' +import { characterFor } from '../characters' const gameStore = useGameStore() const { roomId, gameState, room, yourHand, lastMessage, lastChallenge } = storeToRefs(gameStore) const selected = ref(new Set()) +const justPlayedId = ref('') +let flashTimer = null const roomPlayers = computed(() => room.value?.players || []) const players = computed(() => gameState.value?.players || []) @@ -173,53 +152,316 @@ const playedGroups = computed(() => gameState.value?.playedGroups || []) const isMyTurn = computed(() => currentPlayerId.value === (gameStore.originalPlayerId || gameStore.playerId)) const winnerId = computed(() => gameState.value?.winnerId) const winnerLabel = computed(() => winnerId.value ? shortId(winnerId.value) : '未知') -const lastMessageIsError = computed(() => /失敗|吹牛/.test(lastMessage.value || '')) +const currentLabel = computed(() => currentPlayerId.value ? shortId(currentPlayerId.value) : '-') + +const lastGameMessage = computed(() => lastMessage.value || '') +const challengeText = computed(() => { + const c = lastChallenge.value + if (!c) return '' + const who = c.systemChallenge ? '系統' : shortId(c.challengerId) + return c.isBluff ? `${who} 質疑:吹牛被逮!` : `${who} 質疑失敗——是真話!` +}) + +// 依 player id 找座位 +function seatIndexOf(playerId) { + return players.value.findIndex((p) => p.id === playerId) +} + +// 出牌瞬間標記該座位拋牌動畫 +watch(() => gameState.value?.playedGroups?.length, (n, old) => { + if (n && n > old) { + const g = playedGroups.value[playedGroups.value.length - 1] + if (g) { + justPlayedId.value = g.playerId + if (flashTimer) clearTimeout(flashTimer) + flashTimer = setTimeout(() => { justPlayedId.value = '' }, 1000) + } + } +}) -// 每局(目標牌或 round 改變)清除選牌 watch([targetCard, roundNumber], () => { selected.value = new Set() }) function shortId(id) { - return id ? id.substring(0, 8) + '...' : '-' + return id ? id.substring(0, 4) + '…' : '-' } - function toggleSelect(index) { const next = new Set(selected.value) - if (next.has(index)) { - next.delete(index) - } else { - if (next.size >= 3) return - next.add(index) - } + if (next.has(index)) next.delete(index) + else { if (next.size >= 3) return; next.add(index) } selected.value = next } - function playSelected() { if (selected.value.size < 1 || selected.value.size > 3) return gameStore.playCard([...selected.value]) selected.value = new Set() } - -function startGame() { - gameStore.startGame() -} - -function restartGame() { - gameStore.restartGame() -} - -function challenge() { - gameStore.challenge() -} +function startGame() { gameStore.startGame() } +function restartGame() { gameStore.restartGame() } +function challenge() { gameStore.challenge() } \ No newline at end of file +.tavern-bg::before { + content: ''; + position: absolute; + inset: 0; + background-image: + repeating-linear-gradient(92deg, rgba(120, 80, 40, 0.06) 0 3px, transparent 3px 22px); + background-size: 100% 100%; + opacity: 0.5; +} +.candle { + position: absolute; + bottom: 8%; + width: 8px; + height: 22px; + border-radius: 3px; + background: #7a5a3a; +} +.candle::before { + content: ''; + position: absolute; + top: -14px; + left: 2px; + width: 4px; + height: 14px; + border-radius: 50%; + background: radial-gradient(circle at 50% 70%, #fff6c0, #ffb84d 60%, transparent); + filter: blur(1px); + animation: flick 0.4s ease-in-out infinite alternate; +} +.candle::after { + content: ''; + position: absolute; + top: -26px; + left: -16px; + width: 40px; + height: 30px; + border-radius: 50%; + background: radial-gradient(closest-side, rgba(255, 190, 90, 0.22), transparent); + filter: blur(6px); + animation: flick 0.7s ease-in-out infinite alternate; +} +.c1 { left: 12%; } +.c2 { right: 12%; } +.c3 { left: 50%; transform: translateX(-50%); top: 72%; } +.dust { + position: absolute; + inset: 0; + background-image: + radial-gradient(1px 1px at 20% 30%, rgba(255, 255, 255, 0.25), transparent), + radial-gradient(1px 1px at 70% 20%, rgba(255, 255, 255, 0.18), transparent), + radial-gradient(1px 1px at 40% 70%, rgba(255, 255, 255, 0.14), transparent), + radial-gradient(1.5px 1.5px at 85% 60%, rgba(255, 255, 255, 0.2), transparent); + animation: dustFloat 9s ease-in-out infinite; +} + +/* ---- 等待室 ---- */ +.overlay-panel { + position: relative; + z-index: 2; + min-height: 50vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + background: rgba(10, 8, 14, 0.55); + border-radius: 18px; + backdrop-filter: blur(3px); +} +.waiting-title { + font-size: 1.6em; + color: #ffd79a; + text-shadow: 0 0 14px rgba(255, 160, 60, 0.5); + margin: 0; +} +.waiting-players { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + max-width: 560px; +} +.waiting-player { + display: flex; + align-items: center; + gap: 6px; + background: rgba(0, 0, 0, 0.45); + border: 1px solid color-mix(in srgb, var(--c) 60%, transparent); + border-radius: 20px; + padding: 6px 12px; + color: #eee; + font-size: 13px; + animation: popIn 0.5s ease-out both; +} +.wp-emoji { font-size: 18px; } +.me-tag { background: #ffd43b; color: #222; border-radius: 8px; padding: 0 4px; font-weight: 700; font-size: 10px; } +.count { color: #aaa; margin: 0; } + +/* ---- 遊戲桌 ---- */ +.game-scene { + position: absolute; + inset: 0; + z-index: 1; +} +.table-wrap { + position: absolute; + left: 50%; + top: 52%; + transform: translate(-50%, -50%); + width: min(720px, 92%); + height: 320px; +} +.table-felt { + position: absolute; + inset: 0; + border-radius: 46% 46% 46% 46%; + background: + radial-gradient(ellipse at 40% 30%, #2f7d4f, #1e5a3a 60%, #144229 100%); + box-shadow: + 0 22px 40px rgba(0, 0, 0, 0.65), + inset 0 0 0 10px #5a3d22, + inset 0 0 0 14px #3a2a18, + inset 0 0 70px rgba(0, 0, 0, 0.55); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + animation: tableIn 0.8s cubic-bezier(0.34, 1.3, 0.64, 1) both; +} +.round-info { + display: flex; + gap: 14px; + color: #ffe9c8; + font-size: 14px; + text-shadow: 0 1px 3px #000; +} +.winner-text { color: #ffd43b; font-weight: 700; } +.target-card { + display: flex; + align-items: center; + gap: 8px; + background: rgba(0, 0, 0, 0.35); + padding: 6px 16px; + border-radius: 12px; +} +.tc-label { color: #ffd79a; font-size: 13px; } +.tc-value { + font-size: 26px; + font-weight: 800; + color: #fff; + letter-spacing: 1px; + text-shadow: 0 0 10px rgba(255, 200, 90, 0.6); +} +.played-area { + display: flex; + gap: 10px; + min-height: 26px; +} +.played-chip { + background: rgba(0, 0, 0, 0.45); + padding: 3px 10px; + border-radius: 14px; + color: #fff; + font-size: 13px; + animation: popIn 0.4s ease-out both; +} +.challenge-banner { + padding: 6px 14px; + border-radius: 10px; + font-size: 14px; + font-weight: 700; +} +.challenge-banner.bluff { background: rgba(220, 60, 60, 0.75); color: #fff; } +.challenge-banner.truth { background: rgba(70, 160, 110, 0.75); color: #fff; } +.msg-line { + color: #ffdfa0; + font-size: 13px; + min-height: 18px; + text-shadow: 0 1px 2px #000; +} + +/* ---- 底部操作區 ---- */ +.action-deck { + position: relative; + z-index: 3; + margin-top: 440px; + display: flex; + flex-direction: column; + align-items: center; + gap: 14px; + padding: 20px; + background: linear-gradient(180deg, rgba(20, 15, 25, 0.6), rgba(10, 8, 14, 0.85)); + border-radius: 18px; +} +.hand { + display: flex; + gap: 10px; + flex-wrap: wrap; + justify-content: center; + perspective: 600px; +} +.hand-card { + width: 64px; + height: 90px; + border: 2px solid #c9a86a; + border-radius: 10px; + background: linear-gradient(150deg, #fff8ec, #f0e2c4); + color: #5a3d22; + font-size: 20px; + font-weight: 800; + cursor: pointer; + transform-style: preserve-3d; + transition: transform 0.2s, box-shadow 0.2s; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); +} +.hand-card:hover { transform: translateY(-8px) rotateX(12deg); } +.hand-card.sel { + transform: translateY(-16px) rotateX(8deg); + border-color: #ffd43b; + box-shadow: 0 0 16px rgba(255, 212, 59, 0.8); +} +.actions { + display: flex; + gap: 14px; +} + +@keyframes flick { + from { transform: translateY(1px) scaleY(1); opacity: 0.85; } + to { transform: translateY(-2px) scaleY(1.25); opacity: 1; } +} +@keyframes dustFloat { + 0%, 100% { transform: translateY(0); opacity: 0.6; } + 50% { transform: translateY(-14px); opacity: 1; } +} +@keyframes popIn { + from { transform: scale(0.6); opacity: 0; } + to { transform: scale(1); opacity: 1; } +} +@keyframes tableIn { + from { transform: scale(0.75); opacity: 0; } + to { transform: scale(1); opacity: 1; } +} +.fade-enter-active, .fade-leave-active { transition: opacity 0.4s; } +.fade-enter-from, .fade-leave-to { opacity: 0; } + diff --git a/client/src/components/Lobby.vue b/client/src/components/Lobby.vue index 6dd3a7e..f4693a2 100644 --- a/client/src/components/Lobby.vue +++ b/client/src/components/Lobby.vue @@ -1,72 +1,72 @@ diff --git a/client/src/components/PlayerSeat.vue b/client/src/components/PlayerSeat.vue new file mode 100644 index 0000000..40a6033 --- /dev/null +++ b/client/src/components/PlayerSeat.vue @@ -0,0 +1,272 @@ + + + + + diff --git a/docs/research/minimax-ai-game-visual/10_rtx5080本機動畫方案.md b/docs/research/minimax-ai-game-visual/10_rtx5080本機動畫方案.md new file mode 100644 index 0000000..08e1d6e --- /dev/null +++ b/docs/research/minimax-ai-game-visual/10_rtx5080本機動畫方案.md @@ -0,0 +1,198 @@ +# RTX 5080(16GB・Blackwell sm_120)+ ComfyUI 開源 2D 卡通角色動畫方案 + +**調查日期:** 2026-08-07 +**調查者:** Hermes 研究子代理(minimax-ai-game-visual 工作流系列 #10) +**目標硬體:** RTX 5080(16GB GDDR7、Blackwell sm_120、CUDA、Windows)+ 自家 ComfyUI +**既有管線:** ComfyUI + IP-Adapter + ControlNet DWpose(角色一致性),有 8 個 2D/Q 版/卡通女性立繪 +**需求:** 開源免費、在地執行,把 8 個 2D 角色做成「待機小動作迴圈」(眨眼、髮絲、呼吸、微笑)與其他動畫素材,輸出轉網頁用 WebM(VP9)/APNG。 + +> **誠實標註原則:** 本文所有「可查證硬規格」均有資料來源;無法從權威來源確證的數字一律標「未查到」。風格/配方判斷明確標「建議」。 + +--- + +## 摘要 + +1. **在地 16GB 跑得動、且最適合「2D/cel/toon 待機迴圈」的主力是「AnimateDiff(SD1.5 底模+2D LoRA)」**——它是在靜態圖模型上加一層「時間一致性」motion module,風格完全由你選的 2D 底模/LoRA 決定,最契合你既有的 8 張 2D 立繪,VRAM 需求極低(SD1.5 案例遠低於 16GB,安全)。→ **給 2D 待機迴圈使用的首選**。 +2. **做「更強動作/720p」的高階圖生視訊,2026 年 8 月當紅且官方在 ComfyUI 原生支援的是 Alibaba **Wan2.2**(Apache-2.0,可商用)**:`Wan2.2-TI2V-5B`(混合 T2V+I2V,720P@24fps,官方明言可在 4090 等消費卡上跑,ComfyUI 原生 offload 下「5B 版在 8GB 就能放得下」)、`Wan2.2-I2V-A14B`(14B MoE,480p/720p,需靠 fp8/GGUF+offload)。→ **給「高品質動作」的首選**。 +3. **RTX 5080/Blackwell(sm_120)的關鍵設定**:必須用支援 Blackwell 的 PyTorch(CUDA 12.8+;ComfyUI 官方現行文件對 NVIDIA 建議 **torch cu130**)。用舊版 torch/cu124 會直接跑不動或極慢。→ 更新到最新 ComfyUI 隨附的 cu128/cu130 環境即可。 +4. **推薦工作流(8 角色→待機迴圈→WebM/APNG)分三階段**:A) AnimateDiff 做 2D 無縫迴圈(最省、風格最準);B) Wan2.2 5B I2V 做較高動態(480p 優先,16GB 安全);C) 輸出用 ComfyUI 內建 `SaveAnimatedPNG`→APNG,或用 ffmpeg 轉 `WebM(VP9 + alpha)`。全程 16GB 安全。 +5. **16GB 上「跑不動/不建議」的模型**:Mochi-1(單卡官方 ~60GB,ComfyUI 優化後 <20GB,16GB 太勉強)、HunyuanVideo(720p@129f 官方表列 60GB;改用 **HunyuanVideo-1.5**,官方最低 ~14GB(含 offload),才在 16GB 邊緣可行)、Wan2.2 14B 720p(需較重量化/offload,非首選;降落 480p 或用 5B)。 +6. **與 4090/5070 比較**:5080(16GB、Blackwell)在「開源視訊模型」是 2026 年消費卡甜點位——比 4090(24GB)VRAM 少但 Blackwell FP8/FP4 算力與耗電更好;比 5070(12GB)VRAM 多、14B 模型較可行。量化的需求:越高階模型越要靠 fp8/GGUF,這是省 VRAM 但劣化品質的雙面刃。 +7. **陷阱**:720p+長幀數+堆疊 ControlNet/IP-Adapter 最容易爆 VRAM;無縫迴圈要「首幀=末幀」或 Latent Loop,否則接縫明顯;網頁透明背景要用 chromatic key+VP9 alpha(或直接 APNG),否則白底;SDXL 版 AnimateDiff+其他外掛疊在 16GB 會吃緊。 + +--- + +## 一、候選模型在 ComfyUI 的支援與 VRAM 需求(逐項查證) + +| 模型 / 版本 | ComfyUI 支援 | 官方/權威 VRAM 需求 | 在 16GB 可行度(5080) | +|---|---|---|---| +| **AnimateDiff(SD1.5 版)** | 原生透過 `ComfyUI-AnimateDiff-Evolved`(Kosinkadink)等節點,「在 SD1.5/SDXL checkpoint 上疊 motion module」;支援 Motion LoRA | 文件未列硬性數字;因架構是在 ~5GB(SD1.5 fp16)底模上加工,慣用 <8GB 即可 | ✅ 非常安全(遠低於 16GB) | +| **AnimateDiff(SDXL 版)** | 同上(mm_sdxl 系列 motion module、另有 beta adapter) | SDXL fp16 底模 ~13GB,疊 motion 後 16GB 偏緊、需小心外掛 | ⚠️ 邊緣(單純底模可以,疊 ControlNet+IP-Adapter 會吃緊) | +| **Stable Video Diffusion 1.1 / XT** | ComfyUI 內建原生節點(`SVD_img2vid_Conditioning` 等),HuggingFace `stabilityai/stable-video-diffusion-img2vid[-xt]` | 官方未列統一 VRAM;慣用 1024×576・25 幀、約 8–12GB 可行(offload 後) | ✅ 可行(但為 2023 舊模型,品質落後,推薦度低) | +| **Wan2.1(T2V-1.3B / 5B / 14B,480p/720p)** | ComfyUI 原生支援,Comfy-Org repackaged | 1.3B 極輕量各家皆可;14B 需 fp8/量化與層級 offload | ✅(1.3B)/⚠️(14B 需量化);已被 Wan2.2 取代 | +| **Wan2.2-TI2V-5B**(混合 T2V+I2V,720P@24fps) | **ComfyUI 原生(2025-07-28 起)**,Apache-2.0 | 官方 ComfyUI 文件明言「5B 版在 8GB 就能放得下(配 ComfyUI 原生 offload)」;官方「5 秒 720p < 9 分鐘(單消費卡)」 | ✅ 很安全,**本報告 I2V 首選** | +| **Wan2.2-I2V-A14B / T2V-A14B**(14B MoE,480p/720p) | ComfyUI 原生;提供 fp8 high/low noise 兩子模型、另有 GGUF 量化(`bullerwins/Wan2.2-I2V-A14B-GGUF`) | 官方指令在 720p 需厚重 offload(`--offload_model --t5_cpu`);16GB 要強量化+offload | ⚠️ 480p 可行;720p 需 GGUF/offload、較慢 | +| **LTX-Video 0.9.5 / 2.0 / 2.3**(2B) | ComfyUI 原生內建 LTX 節點(`EmptyLTXVLatentVideo` 等) | 2B 架構極省記憶體,慣用 <8GB;本調查未取得官方單一 VRAM 數字 | ✅ 很安全;快但細節/風格控制較弱 | +| **Mochi-1(480p)** | ComfyUI 原生(`EmptyMochiLatentVideo`、ModelMergeMochiPreview);2024-11-05 官方宣布消費卡原生支援 | genmo 官方:單 GPU 需 **~60GB**;「ComfyUI 可優化到 **<20GB**」 | ⚠️ 16GB 太勉強,**不建議用 5080 跑** | +| **HunyuanVideo(13B,720p,129 幀)** | ComfyUI 原生 Hunyuan 節點 | 官方記憶體表:720px1280px129f ≈ **60GB**(fp8 可省) | ❌ **不要用 5080 跑 720p**;見下方 1.5 | +| **HunyuanVideo-1.5(2025-11-21)** | ComfyUI 原生(`HunyuanVideo15ImageToVideo` 等) | 官方 README:「**Minimum GPU Memory: 14 GB(含 model offloading)**」;另 480p I2V step-distilled 模型;Wan2GP 號稱可低至 6GB | ⚠️ 16GB 邊緣可行(需 offload) | +| **MiniMax H3(open weights)** | ComfyUI 原生(2026 起,T2V/I2V/R2V 範本) | 大型 omni-modal 模型;16GB 可行性**未查到**;官方建議面向雲/高階 GPU | ❓ 不建議本地 16GB;走 API(見系列 #01/#03/#07) | + +> 註:表中 WAN 14B、Mochi、Hunyuan 等「GB」多為官方文件的單卡估算;實際落地依解析度/幀數/是否 offload/量化精度浮動,屬「數量級」而非精確值,請以官方連結為準。 + +### 1.1 逐項查證細節 + +- **AnimateDiff**:`ComfyUI-AnimateDiff-Evolved` README 明言「motion module 與 SD LoRA 可共存、可在單趟由 512² upscale」,並支援 `mm_sd_v15_v2`(SD1.5)與 Hotshot/SDXL 架構;運動可用 Motion LoRA 調控。官方 motion adapter 存於 HF `guoyww/animatediff`(Apache-2.0)與 `guoyww/animatediff-motion-adapter-sdxl-beta`。→ **最適合把既有 2D 立繪做「眨眼/髮絲/呼吸」這種小動作**(因為它本質就是「讓靜態圖模型在時間上一致地動」)。 +- **SVD**:HF `stabilityai/stable-video-diffusion-img2vid-xt`(17.2 萬次下載)為官方出圖後接視訊;2023 年模型,量產「23–25 幀、約 1024×576」,慣用 8–12GB。偏好寫實,2D/toon 表現普通。→ 2026 年有更好選擇,**僅列為後備**。 +- **Wan2.2**(Aliyun,Apache-2.0;ComfyUI 官方 2025-07-28 Day-0 支援):官方提出三款開源: + - `Wan2.2-TI2V-5B`:單模型吃 T2V+I2V,720P@24fps,於 4090 級消費卡可跑(官方)。 + - `Wan2.2-I2V-A14B`:14B MoE 圖生視訊,480p/720p。 + - `Wan2.2-T2V-A14B`:14B MoE 文生視訊,480p/720p。 + - 另 `Wan2.2-Animate-14B`(角色動畫/替換,用 driving video 帶動角色動作+DWpose)與 `Wan2.2-S2V-14B`(語音帶動)。 + - ComfyUI 文件的 I2V/A14B 工作流用 high/low noise 兩個 fp16 子模型;另有 GGUF 量化方便 16GB。 +- **LTX-Video**:官方高效 2B 模型(Lightricks,548K 下載),ComfyUI 有影像/文字/多幀控制工作流,強調長敘述 prompt;極省記憶體,適合快速迭代。 +- **Mochi**:genmo 1,「~60GB 單 GPU、ComfyUI 可優化 <20GB」;480p。 +- **HunyuanVideo**:騰訊 13B,官方表列 720p@129f 需 60GB;1.5 版大幅改進(最低 14GB offload、480p I2V distilled),是 16GB 上唯一可行的 Hunyuan 家族。 + +--- + +## 二、哪些特別適合「2D / cel / toon 卡通角色」風格 + +| 模型 | 2D/toon 適合度 | 理由/方法 | +|---|---|---| +| **AnimateDiff+2D 底模+2D LoRA** | ★★★★★(最準) | 風格 100% 由你選的 2D/SD1.5 checkpoint 與 LoRA 決定,可直接對齊你既有立繪畫風(Q版/卡通/toon)。Motion LoRA 控制動作幅度。**建議的首選**。 | +| **Wan2.2(5B/14B I2V)** | ★★★☆ | Wan 偏向電影寫實/美學,也能出卡通/吉普力風,但要靠 prompt(如 `anime, cel shading, 2D cartoon style`)與 LoRA 拉回來;動作品質高。做「較大動作」時用。 | +| **HunyuanVideo-1.5** | ★★★☆ | 社群多 2D/動畫 LoRA 與微調(如按動畫資料訓練),在 16GB 邊緣可用(offload)。 | +| **LTX-Video(2.3)** | ★★★ | 快、便宜,細節與風格控制較弱;適合快速草稿/非精緻動畫。 | +| **SVD** | ★★☆ | 偏寫實,toon 表現有限。 | + +**風格建議(這是「建議」,非官方規定):** 若目標是「把既有 2D 立繪活起來」且動畫幅度小(眨眼、髮絲、呼吸、微笑),**用 AnimateDiff 最能保畫風一致**;若要「有明顯動作/鏡頭的短動畫」,再用 Wan2.2 5B I2V。兩者可分工:小動作→AnimateDiff,大動作/720p→Wan。 + +--- + +## 三、RTX 5080 / Blackwell(sm_120)在 ComfyUI 的相容性與加速設定 + +- **硬體規格(NVIDIA 官方)**:RTX 5080 = 16GB GDDR7、10752 CUDA cores、**1801 AI TOPS(FP4)**、約 171 TFLOPS(FP32)、Blackwell 架構。消費級 Blackwell 的計算能力標記為 **sm_120**。 +- **PyTorch / CUDA 要求(關鍵)**:RTX 50 系列(sm_120)需要 **CUDA 12.8+ 的 PyTorch**(torch cu128 起才原生支援 Blackwell)。**ComfyUI 官方「系統需求」頁對 NVIDIA 現行建議是 `pip install torch ... --extra-index-url https://download.pytorch.org/whl/cu130`(CUDA 13.0)**。→ 用 ComfyUI 當期 Windows 桌面安裝包/`ComfyUI_Windows_portable` 隨附的 torch 即可;若自行建環境,**務必用 cu128/cu130**,不要沿用舊的 cu121/cu124 環境。 +- **已知坑**:部分第三方節點的編譯 kernel 若只針對舊架構 build,在 sm_120 上可能回退或需重編(2026 年主流節點均已支援,但遇到「某節點在 50 系錯誤/慢」時,先更新 ComfyUI、torch 與該節點)。FlashAttention 亦需 sm_120 版 build。 +- **FP4/FP8**:Blackwell 有第五代 Tensor Core,原生加速 fp8/fp4;ComfyUI 對 Wan、HunyuanVideo 等已支援 fp8 與層級 offload,這對 16GB 是關鍵省記憶體手段(但會微微劣化品質)。 +- **既有管線相容**:IP-Adapter、ControlNet DWpose 皆為成熟節點,在最新 ComfyUI+cu130 上正常運作;與 AnimateDiff/Wan 同圖堆疊時留意 VRAM(見陷阱章節)。 + +--- + +## 四、推薦工作流:8 個 2D 角色 → 待機迴圈 → WebM/APNG(每步註明 VRAM 是否安全落在 16GB) + +> 前置:更新 ComfyUI+torch(cu128/cu130)。建議把 8 張立繪批次迴圈,先跑 1 張驗證再上全量。 + +### 階段 A — AnimateDiff 做「2D 無縫待機迴圈」(最省、畫風最準) + +| 步驟 | 節點 / 模型 | 建議值 | 16GB VRAM | +|---|---|---|---| +| A1 | `Load Checkpoint`:2D/SD1.5 底模(與你的立繪同畫風,fp16;建議 ~5GB 級 SD1.5) | 底模解析度如 768×768 或底模原生 | ✅ 極安全(<6–8GB) | +| A2 | `AnimateDiff Loader`:motion module `mm_sd_v15_v2`(SD1.5) | context length 16–32 | ✅ | +| A3 | `AnimateDiff` 迴圈設定:選「Latent Loop」/首幀=末幀使輸出可無縫迴圈 | — | ✅ | +| A4 | (可選)疊 2D style LoRA 強化 toon 一致性;疊 IP-Adapter 鎖定角色臉 | 強度 0.5–0.9(建議值) | ✅(單一 LoRA)/⚠️(再疊 ControlNet+IP-Adapter 才開始吃緊) | +| A5 | 空 Latent(`EmptyLatentImage`) | 512×512~768×768、frames=16 左右 | ✅ | +| A6 | `KSampler`+Scheduler | steps 20–25 | ✅ | +| A7 | `VAE Decode` → `SaveAnimatedPNG`(APNG)或 `SaveVideo`(mp4) | 見階段 C 轉 WebM | ✅ | + +**VRAM 結論(階段 A):SD1.5+AnimateDiff+1 支 2D LoRA,16GB 綽綽有餘。** 若要 SDXL 版 AnimateDiff,僅純底模(fp16 ~13GB)接近 16GB 上限,疊外掛會吃緊——**建議 2D 迴圈用 SD1.5 版**。 + +### 階段 B — Wan2.2 5B I2V 做「較高動態短動畫」(16GB 可行) + +| 步驟 | 節點 / 模型 | 建議值 | 16GB VRAM | +|---|---|---|---| +| B1 | 更新 ComfyUI,載入範本 `Video > Wan2.2 5B video generation`(官方內建) | — | — | +| B2 | `Load Diffusion Model`:`wan2.2_ti2v_5B_fp16.safetensors` | — | ✅(官方:5B 配 offload 8GB 可放) | +| B3 | `Load VAE`:`wan2.2_vae.safetensors`;`Load CLIP/Text`:`umt5_xxl_fp8_e4m3fn_scaled` | — | ✅ | +| B4 | `EmptyWanVideoLatent`(Wan 系列原生節點) | **480p(如 832×480)優先**、則可上 720p(1280×704) | ✅ 480p 很安全;720p 仍需 offload,建議先 480p 驗證 | +| B5 | I2V conditioning:首幀 = 你的立繪;正 prompt 寫待機動作(`breathing, hair swaying, gentle smile`+風格詞) | frames 81–121;可加 `Video Extend`(每段 +77 幀) | ✅ 480p+短幀安全;拉長/拉高解析度才逼近 16GB | +| B6 | `KSampler`+Wan 專屬 Scheduler(模型自動) | steps ~20;可加 Lightx2v 4-steps LoRA 求快 | ✅ | +| B7 | `VAE Decode`→ 輸出 mp4/APNG | 見階段 C | ✅ | + +**VRAM 結論(階段 B):Wan2.2 5B 在 480p 下 16GB 安全(官方明言 8GB 可放,配 offload)。** 要到 720p 建議先測 1 張,若不穩就降到 480p 或開 `低VRAM/offload`。 + +### 階段 C — 輸出 WebM(VP9) / APNG(網頁用) + +| 輸出 | 做法 | +|---|---| +| **APNG(要透明背景)** | ComfyUI 內建 `SaveAnimatedPNG` 直接出 APNG;二值(RGB+alpha)即可,瀏覽器原生支援。 | +| **WebM(VP9 + alpha)** | ComfyUI `SaveVideo` 出 mp4 → ffmpeg 二進制轉:輸入原圖(或用亮/綠幕 key)→ `c:v libvpx-vp9 -pix_fmt yuva420p`(VP9 alpha)。若要無接縫迴圈,確保階段 A/B 已做「Latent Loop/首幀=末幀」,並在 ffmpeg 用 `-stream_loop -1` 播。 | +| **無透明需求** | 直接 `SaveVideo`(mp4/H.264)或轉 VP9 WebM 即可,體積小、播放順。 | + +> WebM/APNG 的業界格式取捨細節另見系列 #04《網頁素材整合技術》。此處僅列 ComfyUI 端產出與轉檔最小動作。 + +--- + +## 五、與 4090 / 5070 比較:5080 的優勢劣勢(量化/Offload 需求) + +| 面向 | RTX 5080(16GB・Blackwell) | RTX 4090(24GB・Ada) | RTX 5070(12GB・Blackwell) | +|---|---|---|---| +| VRAM | 16GB(居中) | **24GB(最大餘裕)** | 12GB(最小) | +| 架構 | Blackwell sm_120 | Ada Lovelace sm_89 | Blackwell sm_120 | +| FP4 AI TOPS(官方) | **1801**(查證) | 未查到(慣傳 ~1321) | 未查到(慣傳 ~988) | +| 開源視訊模型契合度 | ★★★★★(16GB 涵蓋 Wan2.2 5B、HunyuanVideo-1.5、AnimateDiff、LTX) | ★★★★★(VRAM 大,14B/720p 更從容) | ★★★(12GB 下 14B 模型更需低量化/offload) | +| 14B(Wan/Hunyuan)情形 | 需 fp8/GGUF+offload;480p 順暢 | 720p 較順(24GB) | 需低量位(Q4~Q6)+offload | +| 量化/Offload 需求強度 | 中(5B 不需、14B 需要) | 低–中 | 高(12GB 較緊) | + +**優勢:** 5080 為 2026 年開源視訊模型的「甜點位」——比 5070 多 4GB(14B 明顯較可行),且 Blackwell FP8/FP4 原生加速讓 Wan/Hunyuan 等現代模型較 Ada(4090)更快、更省電。 +**劣勢:** 比 4090 少 8GB 餘裕,14B 模型的 720p 高幀長段仍需靠量化+offload,品質與速度會略打折;若要「無腦 720p 14B」不如 4090。 +> 4090/5070 的 AI TOPS 數字本文標「未查到」(僅 5080 的 1801 經 NVIDIA 官方頁查證),避免臆造。 + +--- + +## 六、陷阱與避坑清單(降低成本/防爆 VRAM) + +1. **爆 VRAM 主因**:同時疊 ControlNet+IP-Adapter+SDXL 底模+長幀數+高解析。解法=一次只開需要的外掛、解析度降、開 ComfyUI `--lowvram`/offload、用 fp8/GGUF。WLan 14B 開 720p +長幀最易爆——先 480p。**Mochi 720p、HunyuanVideo 720p 在 16GB 直接不要碰**(官方 ~60GB)。 +2. **無縫迴圈**:不做「Latent Loop/首幀=末幀」迴圈,WebM 播放會出現跳接縫。輸出前用 `LatentFromBatch/Concat` 或 Wan `Video Extend` 對齊。 +3. **透明背景**:網站常用透明角色。VP9 alpha(`yuva420p`)或 APNG 都要在生成時保留 alpha(亮/綠幕 key 或輸出 PNG 序列);直接輸 mp4 沒有 alpha。 +4. **Blackwell 環境**:用錯 torch(cu121/cu124)會「裝好了卻跑不動」。務必 cu128/cu130;第三方節點報錯先更新。 +5. **品質 vs VRAM 的量化取捨**:16GB 上 14B 模型預設降量位置化(fp8/GGUF)會微微劣化,非必要不必強上 14B——Wan2.2 5B 在 480p 已很好,成本/品質比最優。 +6. **降成本**:8 角色只做「待機小迴圈」,用階段 A(AnimateDiff,秒級、零額外 GPU 成本)即可覆蓋大部分;只有少數「重點鏡頭」才花時間跑階段 B 的 Wan。時間即成本,480p+短幀+Lightx2v 4-steps 加速 LoRA 能大幅壓縮單段時間。 +7. **別把開源當萬能**:若追求電影級,MinimmH H3 等走 API(見系列 #01/#03/#07),本地 5080 專攻「可控、廉價、批量」的遊戲素材生成。 + +--- + +## 七、可行動建議(對本遊戲專案) + +- **主推「雙軌」**:**AnimateDiff(SD1.5+2D LoRA) 產 8 個角色的待機迴圈(眨眼/髮絲/呼吸/微笑)**;**Wan2.2-TI2V-5B I2V(480p) 做少量高動態短動畫**。先跑 1 角色 2 段驗證畫風與迴圈,再批次 8 角色。 +- **輸出規格**:待機迴圈→APNG(或 WebM VP9+alpha);網頁播放用 `SaveAnimatedPNG`/ffmpeg 轉 WebM。無縫迴圈務必「首幀=末幀」。 +- **第一批下載(目錄)**:Wan2.2 5B + wan2.2_vae + umt5 fp8 text encoder(見官方 ComfyUI Wan2.2 教學);AnimateDiff motion module + 一支 2D/anime LoRA;如要做 Hunyuan 則抓 1.5 的 480p I2V。 +- **不要**:別在本機 16GB 用 Mochi / HunyuanVideo(720p);14B 模型先試 480p。 + +--- + +## 八、資料來源連結清單 + +**ComfyUI 官方/權威** +- ComfyUI 官方文件(首頁):https://docs.comfy.org/ +- ComfyUI 系統需求(NVIDIA 建議 torch cu130):https://docs.comfy.org/installation/system_requirements +- Wan2.2 官方 ComfyUI 教學(含 5B/14B 模型、VRAM 註記、GGUF):https://docs.comfy.org/tutorials/video/wan/wan2_2 +- Wan2.2 Animate ComfyUI 教學(角色動畫+DWpose):https://docs.comfy.org/tutorials/video/wan/wan2-2-animate +- LTX-Video 0.9.5 ComfyUI 教學(2B,需求:ltx-video-2b + t5xxl):https://docs.comfy.org/tutorials/video/ltxv +- Hunyuan Video ComfyUI 教學(13B 720p 模型、I2V):https://docs.comfy.org/tutorials/video/hunyuan/hunyuan-video +- Minivideo MiniMax H3 open weights 教學:https://docs.comfy.org/tutorials/video/minimax/minimax-h3 +- ComfyUI-AnimateDiff-Evolved(Kosinkadink):https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved + +**模型官方/權威** +- Wan2.2 GitHub(模型表、消費卡 4090 可跑、Apache-2.0):https://github.com/Wan-Video/Wan2.2 +- Wan2.2-TI2V-5B(HF):https://huggingface.co/Wan-AI/Wan2.2-TI2V-5B +- Wan2.2-I2V-A14B(HF):https://huggingface.co/Wan-AI/Wan2.2-I2V-A14B +- Wan2.1(HF,1.3B/14B):https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B / https://huggingface.co/Wan-AI/Wan2.1-T2V-14B +- HunyuanVideo GitHub(記憶體表 720p@129f=60GB、fp8):https://github.com/Tencent-Hunyuan/HunyuanVideo +- HunyuanVideo-1.5 GitHub(最低 14GB(offload)、480p I2V distilled、Wan2GP 6GB):https://github.com/Tencent-Hunyuan/HunyuanVideo-1.5 +- Mochi-1 GitHub(~60GB;ComfyUI <20GB):https://github.com/genmoai/mochi +- LTX-Video(HF):https://huggingface.co/Lightricks/LTX-Video +- AnimateDiff(HF,SD1.5 adapter):https://huggingface.co/guoyww/animatediff +- AnimateDiff SDXL beta adapter(HF):https://huggingface.co/guoyww/animatediff-motion-adapter-sdxl-beta +- SVD 1.1 / XT(HF):https://huggingface.co/stabilityai/stable-video-diffusion-img2vid / https://huggingface.co/stabilityai/stable-video-diffusion-img2vid-xt + +**硬體** +- NVIDIA RTX 5080 官方(16GB GDDR7、10752 cores、1801 AI TOPS、171 TFLOPS):https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5080/ +- NVIDIA RTX 5070 官方:https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5070/ +- Wikipedia GeForce 50 series(Blackwell、RTX 50 於 2025-01 上市):https://en.wikipedia.org/wiki/GeForce_50_series + +**本系列相關報告** +- series #00 總覽、#03 靜態轉動態、#07 成本部署(同目錄 minimax-ai-game-visual/) + +> 說明:SVD、LTX、AnimateDiff 等「慣用 VRAM」之數量級措辭,因官方未給單一硬性數字,本文以「慣用/建議值」+連結呈現;確切值如需可於實測階段以 Windows 工作管理員/`nvidia-smi` 實測修正。 diff --git a/docs/research/minimax-ai-game-visual/11_美術素材需求清單.md b/docs/research/minimax-ai-game-visual/11_美術素材需求清單.md new file mode 100644 index 0000000..abe4537 --- /dev/null +++ b/docs/research/minimax-ai-game-visual/11_美術素材需求清單.md @@ -0,0 +1,91 @@ +# 騙子酒館 — 美術素材需求清單(要生什麼圖 / 什麼影片) + +> 產出:2026-08-06 | 目標硬體:RTX 5080(16GB)+ ComfyUI | 對應 PR #17 的佔位素材替換計畫 +> 系列報告:docs/research/minimax-ai-game-visual/(02 角色繪製、03 靜態轉動態、05 一致性、06 風格指引、10 5080 動畫方案) + +--- + +## 一、總覽:分「圖」與「影片」兩類 + +| 類別 | 用途 | 來源方案 | 優先度 | +|------|------|----------|--------| +| **A. 靜態立繪 PNG** | 8 角色正式立繪(替換 PlayerSeat 的 CSS 佔位) | ComfyUI:FLUX/SD + LoRA 或 IP-Adapter | 🔴 最高 | +| **B. 卡面/牌背/目標牌** | 撲克風卡面、牌背花紋、目標牌 | ComfyUI 文生圖 | 🔴 高 | +| **C. 待機動作迴圈** | 8 角色眨眼/髮絲/呼吸(WebM/APNG) | ComfyUI AnimateDiff 或 Wan2.2 | 🟠 中(先做 1 個試) | +| **D. 氛圍/過場影片** | 過場動畫、行銷片頭 | Wan2.2 I2V 或 MiniMax H3 API | 🟡 低 | +| **E. 酒館背景** | 大廳/牌桌背景襯底 | ComfyUI 文生圖 16:9 | 🟡 低(CSS 已可暫代) | + +--- + +## 二、A. 8 角色正式立繪(最高優先) + +### 規格 +- **尺寸**:1024×1024(再縮到 512 當座位圖),透明背景 PNG(另存白底版備用) +- **畫風**:統一「Q 版 2D 卡通(chibi/cel/toon)」,與現有角色視覺映射一致(docs/角色視覺映射筆記.md) +- **一致性策略**(詳見 05 號報告):「1 支畫風 LoRA × 8 支角色 LoRA」疊加,或 FLUX.2/Nano Banana 多參考圖定稿 + +### 8 角色清單(沿用 characters.js / 視覺映射筆記) +| # | 角色 | 髮色/髮型 | 服裝 | 配件 | 性格 | 標籤色 | +|---|------|-----------|------|------|------|--------| +| 1 | Grok-4 | 波浪橘髮 | 黃色無袖洋裝 | 紅色大蝴蝶結 | 演戲/情緒 | 粉紅 | +| 2 | Kimi | 白銀長直髮 | 深藍洋裝+白領 | 項圈 | 老派/踏實 | 深藍 | +| 3 | Qwen3 | 粉紅短髮 | 灰無袖洋裝 | 圓眼鏡 | 刺兒頭 | 藍紫 | +| 4 | GPT-5 | 黑長直髮 | 黑洋裝 | 無 | 沉穩/謀略 | 黑 | +| 5 | Gemini | 紫短髮 | 淺藍洋裝 | 圓眼鏡+星夾 | 好奇 | 淺紫 | +| 6 | Deepseek | 淺藍短髮 | 深藍灰洋裝 | 鯨魚尾 | 瘋癲 | 藍 | +| 7 | Doubao | 深棕短髮 | 黑洋裝 | 無 | 冷靜 | 淺藍 | +| 8 | Claude | 橘短髮 | 橘洋裝 | 無 | 淡定 | 橘 | + +**每角色需 2 姿勢**:正面表情1(預設)+ 得意/偷笑(出牌時)。共約 16 張。 + +--- + +## 三、B. 卡面 / 牌背 (高) + +- **卡面**(A/K/Q/J/10…目標牌區):簡約撲克風、酒館燙金邊、角色元素點綴。每張 512×712(3:4) +- **牌背**:1 張共用,深綠/深紅酒館圖樣,防看穿(無固定印記)。512×712 +- **目標牌賞識**:1 張放大版 + +--- + +## 四、C. 待機動作迴圈(中 — 先做 1 個 PoC) + +> 優先做 **1 個角色**(建議 Deepseek 或 Claude)試水溫,驗證品質後再批量。 + +| 項目 | 來源 | 動作 | 輸出 | +|------|------|------|------| +| 待機循環(眨眼+髮絲+呼吸) | AnimateDiff(SD1.5 + 2D LoRA,16GB 安全) | 首幀=末幀無縫 | **Animated WebP / APNG**(<128KB) | +| 高動態短動畫(微笑/甩髮) | Wan2.2-5B I2V(480p,16GB 安全) | 圖生視訊 | WebM(VP9) | +| 備援方案 | MiniMax H3 API(0.08 美元/秒) | First/Last-frame | WebM/APNG | + +**網頁引導**:座位用 `` 或 sprite sheet + CSS steps()(見 04 號報告)。避免 8 支同時播全析影片解碼爆。 + +--- + +## 五、D. 過場 / 氛圍影片(低) + +- **過場**:H3/Wan2.2 產 5–8 秒「酒杯碰撞/翻牌/煙霧」段子,WebM + MP4 備援 +- **行銷片頭**:H3 文生影片 8–15 秒(2K 0.13 美元/秒) + +--- + +## 六、E. 酒館背景(低,CSS 已暫代) + +- 大廳/牌桌背景 16:9 深色木紋酒館內景(文生圖,污點/模糊版當襯底) +- 桌布/毛氈紋理替換純 CSS 漸層 + +--- + +## 七、生成 SOP(沿用 #10 報告三階段) + +1. **定畫風**:FLUX/SD + 畫風 LoRA 出 8 角色定稿 → 過濾 → 一致性檢查 +2. **動畫**:AnimateDiff(2D 迴圈)→ Wan2.2(高動態)→ 挑閉合度最佳版 +3. **轉檔**:ffmpeg → WebM(VP9+alpha) / Animated WebP / APNG / sprite sheet +4. **落地**:換掉 PR #17 的 CSS 佔位 → 效能測試(DevTools Performance) + +--- + +## 八、預算速覽(依 07 號報告) +- 靜態圖:FLUX-schnell ~$0.003/張(幾乎可忽略);8 角色約 16 張 < $1 +- 動畫(RTX 5080 自跑):僅電費;品質差強用 H3 API 補:8 角色 × 5 秒 ≈ ¥240(768P) +- MVP 總估 ¥200–600(不含人力)