第 25/60 天
引言
动作场面是漫画最激动人心的部分,也是 AI 漫剧制中最难啃的骨头。静态的 AI 绘画工具默认生成”摆拍”式画面:人物站得笔直、表情呆滞、毫无冲击力。你输入”两个人在打架”,得到的往往是一个人物悬在空中、肢体扭曲、背景干净得像摄影棚的诡异画面。
为什么动作场景这么难?因为漫画的”动感”根本不是画面内元素的运动,而是视觉符号的编码:速度线、冲击波、动态模糊、透视压缩(foreshortening)、多重残影……这些符号是漫画家用手绘语言”欺骗”眼睛的技法。要让 AI 理解并输出这套符号系统,需要把动作场景拆解为「姿态 → 透视 → 特效 → 合成」四个可控制的环节。
本文覆盖:动作场景的构成原理、ControlNet OpenPose/LibrePose 姿态控制、双人战斗分镜的生成管线、速度线与冲击波的后期叠加方案,以及 5 个实战中最高频的翻车问题与修复方法。读完你将能稳定产出”看起来真的在打架”的 AI 漫画分镜。
核心概念
动作场景的四层控制模型
AI 漫画动作场景之所以难,是因为它叠加了四层控制需求,每一层单独可控、又互相影响:
| 控制层 | 主要工具 / 技术 | 解决什么问题 |
|---|---|---|
| 姿态层 | ControlNet OpenPose / LibrePose、3D 姿态参考 | 人物肢体、重心、攻击/受击姿态的骨架控制 |
| 空间层 | ControlNet Depth / Canny、透视网格 | 前后景关系、纵深、镜头角度(俯视/仰视/广角) |
| 表现层 | 动作 LoRA、风格化模型、动态模糊提示词 | 肌肉张力、残影、夸张变形等”漫画感” |
| 特效层 | 后期脚本(速度线/冲击波)、img2img 叠加 | 速度线、放射线、闪光、碎片等动态符号 |
关键术语速查
- OpenPose / LibrePose:ControlNet 的姿态检测模型,从参考图提取骨骼关键点,再把骨架喂给生成模型,让 AI 严格按骨架作画。
- Foreshortening(透视压缩):拳头朝镜头打来时,前臂因透视变短变粗——这是”冲击力”的核心视觉符号。
- 速度线(Speed Lines):从人物或画面中心放射的平行线,表示快速移动。
- 集中线(Concentration Lines):从一点向外放射的直线,用于聚焦注意力或表现冲击瞬间。
- 动态模糊(Motion Blur):运动方向上的拖影,表示高速位移。
- 残影(Afterimage):前一帧的半透明重影,表现连续动作。
- 动作 LoRA:专门训练”动态姿势”或”特写战斗”画风的 LoRA,能让基础模型更擅长画夸张姿势。
提示词层面的动态暗示
基础模型只能”认识”它见过的符号。想让它输出动态感,提示词里要写它认识的动作词和画风词:
dynamic action pose, mid-air kick, motion lines, speed lines,
impact frame, manga style, dynamic perspective, foreshortening,
battle scene, debris, dust clouds, dramatic lighting, high contrast
关键词优先级:动作动词(kicking / punching / dodging)> 镜头词(dynamic angle / low angle)> 符号词(speed lines / impact)> 风格词(manga / ink)。
实战步骤
下面搭建一条”分镜 → 骨架 → 底图 → 特效 → 合成”的完整动作场景流水线。以双人近身格斗分镜为例。
步骤 1:准备动作素材与 ControlNet 模型
首先确保 WebUI/ComfyUI 已安装 ControlNet 扩展和姿态模型。
# SD WebUI 的 ControlNet 模型目录
CN_DIR="/home/user/sd-webui/models/ControlNet"
mkdir -p "$CN_DIR"
# 下载 OpenPose 姿态模型(约 2.4GB,注意放对目录)
wget -O "$CN_DIR/control_v11p_sd15_openpose.pth"
https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth
# 下载为 SDXL 准备的 Union 版(若使用 SDXL 底模)
wget -O "$CN_DIR/controlnet-union-sdxl-1.0.pth"
https://huggingface.co/xinsir/controlnet-union-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors
# 验证文件完整性
ls -lh "$CN_DIR"
姿态参考图哪里来?三种途径:① 用 OpenPose 编辑器(WebUI 插件)手工摆骨架;② 在 3D 软件(Blender/Mixamo)摆好姿势渲染线条图;③ 直接搜”fighting pose reference”素材图让 ControlNet 提取骨架。
步骤 2:手工/程序化摆出双人骨架
推荐用 OpenPose 编辑器插件手工摆骨架。骨架 JSON 通过 API 提交时也可用脚本生成,例如下面的简单姿态配置:
{
"input_image": "/tmp/scene/fight_scene_01.png",
"module": "openpose",
"model": "control_v11p_sd15_openpose [cab867d1]",
"weight": 0.95,
"guidance_start": 0.0,
"guidance_end": 0.6,
"resize_mode": "Resize and Fill",
"control_mode": "Balanced",
"pixel_perfect": true,
"preprocessor_resolution": 512,
"save_detected_map": true
}
weight建议 0.85–1.0:动作场景骨架是硬约束,权重太低姿势会飘。guidance_end设 0.6 左右:让模型在前 60% 采样步数严格跟骨架,后面留出细节自由度,避免手脚僵硬。
步骤 3:用 Python 批量生成战斗分镜
写一个 Python 脚本调用 WebUI 的 API,用”同一角色 LoRA + 固定颜色 prompt + 不同骨架图”批量出图,保证多格战斗的分镜连续性。
#!/usr/bin/env python3
"""批量生成战斗分镜:同一角色、多个骨架图"""
import base64
import json
import time
import urllib.request
WEBUI_URL = "http://127.0.0.1:7860/sdapi/v1/img2img"
BONES = ["/tmp/scene/punch_a.png", "/tmp/scene/dodge_b.png", "/tmp/scene/kick_c.png"]
def b64(path: str) -> str:
with open(path, "rb") as f:
return base64.b64encode(f.read()).decode()
def gen_panel(bone_path: str, out_path: str, panel_no: int):
payload = {
"init_images": [b64(bone_path)],
"prompt": (
"1boy, black haired martial artist, dynamic punch, motion lines, "
"speed lines, manga style, ink, dynamic perspective, "
"lora:action_pose_v1:0.8, <lora:myhero:0.9>"
),
"negative_prompt": "blurry, deformed hands, extra limbs, static pose, photorealistic",
"steps": 28,
"cfg_scale": 7,
"width": 768,
"height": 1080,
"batch_size": 2,
"seed": 20260819, # 固定种子,跨格风格更稳
"override_settings": {"sd_model_checkpoint": "counterfeitXL_v25.safetensors"},
"alwayson_scripts": {
"controlnet": {"args": [{"input_image": b64(bone_path),
"module": "openpose", "weight": 0.95}]}
},
}
req = urllib.request.Request(WEBUI_URL, data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"})
resp = json.loads(urllib.request.urlopen(req).read())
for i, img_b64 in enumerate(resp["images"]):
with open(f"{out_path}_p{panel_no}_{i}.png", "wb") as f:
f.write(base64.b64decode(img_b64))
time.sleep(1.5)
for idx, bone in enumerate(BONES, 1):
gen_panel(bone, "/tmp/scene/output", idx)
print(f"panel {idx} done")
要点:固定 seed + 固定角色 LoRA + 相同的画风 prompt,三管齐下保证跨格角色一致;每张骨架图出 2 张候选,便于挑选。
步骤 4:用 ComfyUI 工作流串联(YAML 片段)
ComfyUI 场景下用节点图实现同样的管线。以下是工作流关键节点的配置片段(可导入 ComfyUI 后调整):
workflow: 战斗分镜_双人_标准
nodes:
- id: 1
type: CheckpointLoaderSimple
params: { ckpt_name: "counterfeitXL_v25.safetensors" }
- id: 2
type: LoraLoader
params: { lora_name: "myhero.safetensors", strength_model: 0.9, strength_clip: 0.8 }
- id: 3
type: ControlNetLoader
params: { control_net_name: "control_v11p_sd15_openpose.pth" }
- id: 4
type: ControlNetApply
params: { strength: 0.95, start_percent: 0.0, end_percent: 0.65 }
- id: 5
type: KSampler
params: { seed: 20260819, steps: 28, cfg: 7, sampler_name: "dpmpp_2m", scheduler: "karras" }
- id: 6
type: SaveImage
params: { filename_prefix: "fight_panel" }
ComfyUI 的优势是可以用 Batch 节点一次处理多张骨架图,连接 LoadImage (batch) → ControlNetApply → KSampler,一次跑完全部分镜。
步骤 5:用 Python (PIL) 叠加速度线与冲击波
AI 生成的速度线往往不够”炸”。最可靠的做法是后期程序化叠加:放射集中线 + 冲击波圆环 + 拖影。
#!/usr/bin/env python3
"""给静态分镜叠加动态符号:集中线 + 冲击波 + 拖影"""
from PIL import Image, ImageDraw, ImageFilter
import math, random
SRC, DST = "/tmp/scene/output_p1_0.png", "/tmp/scene/panel_final.png"
img = Image.open(SRC).convert("RGBA")
W, H = img.size
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
cx, cy = 380, 540 # 冲击中心(拳头的落点)
# 1. 集中线:从中心向外放射的细线
for _ in range(120):
ang = random.uniform(0, 2 * math.pi)
r1 = random.uniform(20, 60)
r2 = random.uniform(150, 900)
x1, y1 = cx + r1 * math.cos(ang), cy + r1 * math.sin(ang)
x2, y2 = cx + r2 * math.cos(ang), cy + r2 * math.sin(ang)
draw.line([x1, y1, x2, y2], fill=(0, 0, 0, 110), width=2)
# 2. 冲击波圆环
for r, w, alpha in [(90, 10, 160), (130, 6, 110), (170, 4, 70)]:
draw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=(255, 255, 255, alpha), width=w)
# 3. 拖影:把原图沿运动方向微移并叠加半透明层
ghost = img.copy().transform(img.size, Image.AFFINE, (1, 0, -40, 0, 1, 0))
ghost.putalpha(90)
ghost = ghost.filter(ImageFilter.GaussianBlur(6))
final = Image.alpha_composite(ghost, img)
final = Image.alpha_composite(final, overlay)
final.convert("RGB").save(DST)
print(f"saved: {DST}")
参数随镜头语言调整:横向闪避用平行速度线(水平方向拉线),爆发冲击用集中线与圆环叠加,高速冲刺则把拖影位移加大到 60–100px。
步骤 6:批处理与出片
最后统一尺寸、加网点/出血框、导出 PNG 序列给排版脚本:
# 统一 768x1080 裁切并转为灰度线稿风格测试(可选)
mkdir -p /tmp/scene/final
for f in /tmp/scene/output_*.png; do
convert "$f" -resize 786x1104^ -gravity center -extent 768x1080
-unsharp 0x1.5 /tmp/scene/final/$(basename "$f")
done
# 生成接触表(contact sheet)供挑选分镜
montage /tmp/scene/final/*.png -tile 3x2 -geometry +8+8 /tmp/scene/contact_sheet.jpg
echo "批量处理完成: $(ls /tmp/scene/final | wc -l) 张分镜"
常见问题
Q1:AI 生成的打斗姿势总是扭曲、手部崩坏怎么办?
动作姿势越夸张,模型越容易崩。三个对策:① ControlNet 的 weight 提到 0.95+,guidance_end 降到 0.5–0.6,让骨架约束占主导;② 给动态姿势装动作 LoRA,专门拯救”模型没见过的高难度姿势”;③ 把手部动作拆成独立步骤——先用骨架图层生成全景,再对含手的区域用 inpaint 局部重绘(提示词 perfect hands, dynamic fist)。
Q2:同一角色在打架时”换了个人”?
动作幅度大时角色特征最容易漂移。核心理由是姿态变化导致面部特征采样不稳定。修复组合拳:固定 seed + 角色 LoRA(权重 0.8–1.0)+ IP-Adapter 绑定角色参考图 + 提示词里固定发色/服装描述词。四者缺一不可,尤其 IP-Adapter 对大幅度姿态变化下的身份保持效果显著。
Q3:速度线、冲击波画不出来,或生成后像”贴在照片上的贴纸”?
提示词可以尝试,但别指望它稳定。把动态符号当成后期层:用本文步骤 5 的脚本程序化生成,或者准备一套速度线/网点 PNG 素材(网上有大量透明底素材),用 PS/图像合成叠上去。后期叠加的另一个好处是线条方向可控——AI 生成的速度线经常方向混乱。
Q4:多人战斗场景两个人”融在一起”、分不开?
一张图里两个角色靠骨架图是不够的,模型分不清谁是谁。推荐方案:分角色分层生成——先单独生成角色 A 的动作图,再单独生成角色 B,最后用合成/深度图拼场景,或用 Segment Anything 分割后合成。进阶做法:用 Photoshop 的 AI 填充或 inpaint 把两个角色分别放在画面左右 1/3 处(构图避让),中间留出”对撞空间”放冲击特效,既清晰又有张力。
Q5:做出来的战斗分镜没有”镜头感”,像摆拍?
摆拍感的根源是缺乏透视张力。检查三点:① 有没有用仰角/俯角(提示词加 low angle shot、bird's eye view);② 有没有透视压缩——向前出拳的角色前臂应该短而粗(foreshortening),不行就手动修;③ 画面是否缺少速度感符号——哪怕姿势对,没有速度线/拖影就看起来像静止摆拍。后期层(速度线+拖影)永远是兜底的”动感保险”。
总结
- 动作场景 = 姿态控制 + 镜头透视 + 动态符号,三者缺一不可;AI 能做好前两项,最后一项(速度线、冲击波)建议后期程序化叠加,稳定又可控。
- ControlNet OpenPose 是动作分镜的地基,权重 0.9+、结束步数 0.6 是经过验证的”硬约束”参数组合,防止姿势漂移。
- 固定 seed + 角色 LoRA + IP-Adapter + 固定的人物描述词是跨格战斗分镜角色一致性的四件套,缺一个就”换人”。
- AI 生成建议”出图优先、特效后置”:先生成干净的姿态底图,再用脚本/PS 叠加速度线、集中线、冲击波和拖影,后期层完全可控,还能随意调整方向与强度。
- 多人打斗按”分角色分层生成 → 合成“进行,比让 AI 一次画两个人失败率低得多;对撞空间留给特效层,画面既清晰又充满张力。
动作场景一旦掌握了这条流水线,你的 AI 漫画就能从”人物插画集”升级为”真正的漫画”——下一期我们将继续攻克第 26 天:AI漫画色彩风格统一,让整部作品的颜色体系牢固而高级。















暂无评论内容