八方向序列拆分 / 8-Direction Sprite Split
The missing step in the character-to-walk-cycle pipeline
- images
- masks
- dir_1
- dir_2
- dir_3
- dir_4
- dir_5
- dir_6
- dir_7
- dir_8
- info
Game-dev pipelines have a hole in them. You can generate an 8-direction character with an image model, animate it into a walking loop with a video model, matte it with Lucida - and then you stare at a video where every frame is a sprite sheet containing all eight directions, and there's no built-in node that splits it into eight clean, aligned animation strips. That's the hole 八方向序列拆分 / 8-Direction Sprite Split fills. It takes your sequence of sprite-sheet frames, cuts each into its eight directions, and outputs dir_1 through dir_8 as RGBA IMAGE sequences plus an info string with the numbers you actually need for a game engine.
The author's intended pipeline is worth internalizing because it's a great map of what's already solved: character image → 8-direction stills (GPTimage2), stills → loop video (Seedance first/last frame), video → frames (native "Get Video Components" for VIDEO→IMAGE, or VHS Load Video from a file), frame-rate drop (VHS "Select Every Nth Image"), matting (Lucida), then this node, then SaveImage (4-channel inputs save as transparent PNG) or VHS Video Combine with format=video/webm + pix_fmt=yuva420p for transparent webm.
The inputs that actually matter
- images - your frames, each a sprite sheet.
- grid_cols / grid_rows / empty_cells - the layout. The classic 3×3 grid with an empty middle is
empty_cells="4"(row-major, 0-indexed).direction_namesdefaults toSW,S,SE,W,E,NW,N,NEfor a sheet where the top row faces the viewer. - bg_mode - where transparency comes from, and this decides your output quality. 已带透明通道 (already transparent, recommended) uses an upstream matting node's alpha via the optional
masksinput - the README measured it gnawing 35% less of your subject than the color-threshold route. 白底转透明 (white-to-transparent) is fast color thresholding but estimates alpha by "how far from white", so white clothes get eaten. 不处理 outputs opaque but still crops by character extent. - edge_shrink / decontaminate - the white-halo fighters. Edge pixels on white backgrounds are white-contaminated;
edge_shrinkclips that fringe (0.15–0.25 with model alpha, 0.35+ with threshold alpha; the README shows white-edge strength dropping 0.048 → 0.016 as you go 0→0.2→0.5).decontaminateback-solves the true foreground color fromobserved = fg×a + white×(1−a)- it helps only ~3% alone, so pair them. - expand_beyond_cell - keep this on. Off, the node cuts strictly at grid lines and feet/capes/staffs get chopped. On, the grid only decides which direction a cell belongs to and the extent comes from the character's connected region.
- align_mode / anchor_type / align_scope - the "switch direction without the character jumping" feature. Default is foot-center anchoring, per-frame nailed down. Why foot-center and not bbox center? Capes and staffs drag the bounding box sideways, but they don't reach the feet - the bottom-band centroid is where the character actually stands. Measured result: per-frame alignment gets direction-to-direction anchor scatter down to 0.76px and kills the 22px cross-frame drift that AI video tends to inject.
Outputs: dir_1…dir_8 (4-channel RGBA) and info with canvas size, anchor coordinates, and the Unity/Godot normalized pivot - paste that pivot into your engine and all eight directions share one coordinate frame.
Why fixed grid instead of connected components
The pack's other sprite splitter uses connected components, which is right for a single static sheet and wrong for animation: as the character moves, its bounding-box ordering drifts across row boundaries, one frame misorders and the whole animation is toast. A fixed grid can't drift. The crop box is also taken as the union across all frames, so the strip stays one consistent size with no inter-frame jumping.
The traps
First, frame-rate mismatch: Seedance outputs 24fps, so your drop rate and output rate must agree - select_every_nth=3 ↔ frame_rate=8, 2 ↔ 12, 1 ↔ 24. Second, the transparent-webm verification trap: alpha lives in a separate WebM sideband, so default ffprobe shows yuv420p and default decoding reads back fully opaque - that's the built-in vp9 decoder ignoring alpha, not a broken file. Decode with -c:v libvpx-vp9 to actually see it. If your character looks grey on a dark background, edge_shrink is too low.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | 视频转出的序列帧,每帧是一张排布着多个朝向的雪碧图。 | |
| grid_cols | INT | 31–8 | 雪碧图的列数。 |
| grid_rows | INT | 31–8 | 雪碧图的行数。 |
| empty_cells | STRING | 4 | 空格子的序号(行优先、从 0 开始,逗号分隔)。 3×3 布局中间留空即填 4。留空表示没有空格。 |
| direction_names | STRING | SW,S,SE,W,E,NW,N,NE | 按「跳过空格后的先后顺序」给每个方向命名,逗号分隔。 默认对应 3×3 中间留空、行 1 面向观众的排布: SW S SE W E NW N NE 名字只用于 info 与你自己辨认,不影响画面内容。 |
| bg_mode | COMBO | 已带透明通道(推荐·上游接抠图节点) | webm 要保留透明就必须先有 alpha。三种来源: 【已带透明通道】把上游抠图节点(Lucida / FeyNobg)的 遮罩接到 masks 输入。**强烈推荐**:模型是按语义判断的, 白衣服不会被误判成背景。实测同等白边水平下, 主体被啃掉的面积比阈值法少 35%。 没接 masks 时会自动退回颜色阈值法,不会报错。 【白底转透明】纯颜色阈值 + 边缘连通性判断,不需要模型、 很快。但它靠「离白色多远」估 alpha,角色身上的白色衣物 天生 alpha 偏低,收边时会被啃出破洞 —— 素材里有白衣服、 白高光时别用这个。 【不处理】输出不透明。仍会按角色范围裁剪、不切断。 |
| bg_threshold | FLOAT | 0.9200.5–1 | 白底判定阈值:像素三通道最小值高于它才算「接近白」。 背景没扣干净就调低,角色边缘被啃掉就调高。 |
| edge_shrink | FLOAT | 0.200–0.95 | 【治白边的主力参数】把边缘那圈「几乎全是背景」的 半透明像素收掉,相当于平滑地向内收一点边。 白底素材的边缘像素本就掺了白,不收掉贴到深色背景就发白。 配模型 alpha(bg_mode=已带透明通道):0.15~0.25 就够。 配颜色阈值法:要 0.35 以上才压得住白边,代价是白色衣物 会被啃出破洞 —— 这也是推荐用模型 alpha 的原因。 0 = 完全不收(白边明显)。 |
| decontaminate | FLOAT | 1.000–1 | 【治白边的第二道】颜色反溢出:把混进边缘像素的白色剥掉。 原理是按 观察色 = 前景×a + 白×(1-a) 反解出真正的前景色。 1.0 = 完全反解(推荐),0 = 不处理。 与上面的收边配合使用,单靠任一个都不够干净。 |
| edge_softness | FLOAT | 1.000.1–4 | 边缘过渡宽度。原图边缘带抗锯齿,过渡太硬会有锯齿白边; 调大更柔和,调小更锐利。 |
| fragment_threshold | FLOAT | 0.050–0.5 | 清掉面积不足主体这一比例的连通碎片。 网格切分会把相邻格子探过来的部件(手杖尖、飘起的衣角) 切进本格,既难看又会撑大自动裁剪的范围。 0 = 不清理;与身体相连的道具不会被误删。 |
| expand_beyond_cell | BOOLEAN | true | 允许角色超出格子边界(强烈建议开启)。 关闭时按格子严格切分,角色只要探出格线就会被切断 ——最常见的是脚、飘起的斗篷和手杖被削掉一截。 开启后格子只用来判定「这是哪个方向」,实际范围由角色 自身的连通区域决定;按质心归属,相邻角色不会被卷进来。 对三种 bg_mode 都有效:选「不处理」时也会在内部算一份 白底检测来圈定范围,输出仍保持不透明。 |
| align_mode | COMBO | 锚点对齐·统一画布(做游戏必选) | 【做游戏素材必选】把 8 个方向对齐到同一张画布上。 不对齐时每个方向各按自己的内容裁剪,尺寸互不相同 (如 208×328 与 192×323),且角色在各自画面里的位置 也不一致 —— 游戏里切换朝向时角色就会跳一下。 开启后:所有方向输出同一尺寸,且锚点(默认脚底中心) 落在画布里的同一个位置,因此切换朝向时角色纹丝不动。 info 输出里会给出画布尺寸与锚点坐标(含 Unity 归一化 pivot),照着填进引擎即可。 |
| anchor_type | COMBO | 脚底中心(推荐) | 用什么当锚点(轴心)。 脚底中心:y 取最低的不透明行,x 取底部窄带的水平质心。 角色站在地面上,脚底才是它在世界里的位置,所以这个最合理。 x 不用包围盒中心,是因为斗篷、披风、手杖会把包围盒 拽向一侧,而它们基本不会垂到脚底。 包围盒底边中心:省掉质心计算,角色没有大幅外挂物时够用。 包围盒中心:适合飞行单位、投射物这类不站地面的素材。 |
| align_scope | COMBO | 逐帧对齐·脚底钉死(推荐) | 对齐的粒度,直接影响动画观感。 【逐帧对齐·脚底钉死】每一帧都把自己的锚点钉在同一点, 等价于人工「一帧一帧对位置」。 行走循环本就该原地播放、位移交给游戏代码,所以 sprite 内部不该有整体漂移。AI 生成的视频往往有 (本仓库实测同方向跨帧漂移达 22px),这个模式能压到 1px。 【按方向统一平移】同方向所有帧平移同样的距离, 保留帧内的重心起伏。方向之间照样对齐。 适合角色本来就该有前后摆动的动作(如挥剑、跳跃), 或素材本身很干净、不需要修漂移时。 |
| auto_crop | BOOLEAN | true | 按内容裁掉多余空白。 裁剪框取「该方向所有帧的并集」,因此整条序列尺寸一致, 既能合成视频,角色也不会在帧间跳动。 |
| crop_padding | INT | 160–200 | 裁剪时在内容外保留的边距(像素)。 给足边距不仅好看,也给后续的描边、发光、 阴影等特效留出余量,免得贴着边显得像被切了。 |
| masksopt | MASK | 可选。已有的透明通道(如上游抠图结果), 配合 bg_mode=已带透明通道 使用。 |
Outputs (9)
| Name | Type | Description |
|---|---|---|
| dir_1 | IMAGE | — |
| dir_2 | IMAGE | — |
| dir_3 | IMAGE | — |
| dir_4 | IMAGE | — |
| dir_5 | IMAGE | — |
| dir_6 | IMAGE | — |
| dir_7 | IMAGE | — |
| dir_8 | IMAGE | — |
| info | STRING | — |