3分越えの戦闘アニメ作画を生成AIで制作する方法 (ComfyUI)

# はじめに

初投稿です。初めまして、ontokyoと申します。
私は、素人が個人で簡単かつ効率的に手描き"風"のアニメを作ることに挑戦しています。
「正邪譚」という生成AIのバトルアニメ動画のシリーズを作り始めたばかりです。
私自身今まで映像制作に携わったことがないので参考書を見ながら手探りで制作しています。

今回アニメの戦闘シーンの作画(背景・キャラクター)を生成AIを使うことで効率よく制作できたので、本記事でその方法を紹介します。
作画にはComfyUIを用いており、**ワークフローのダウンロードも可能**です。
ここでは、AIをどのように使うか、およびそのソフトウェアの操作に関する内容であり、理論的な内容には踏み込みません。また、アニメーションにおける演出や表現に関しては触れません。

そもそもどれぐらいのクオリティの作画なのかについては、下記動画をご参考ください。（戦闘が始まるシーンから再生されます）

<iframe width="560" height="315" src="https://www.youtube.com/embed/6qmzq0zLEF0?si=hqXuYYY4CWcBNrPb&amp;start=59" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

本記事は、AIへの入力データ（テキスト・画像・動画等）について、どのようなデータを入力すれば冒頭の動画のような作画をやってくれるか、サンプルを元に説明します。
ComfyUIの導入、およびその拡張ノードであるComfyUI Managerの導入まで済んでおり、動作できることが前提です。ComfyUI、ComfyUI Managerの導入方法については本記事では取り扱いません。たくさん記事が出ていますのでそちらをご参照いただくようお願いします。

以降の本記事の構成を下記に示します。長いので必要な部分からお読みください。
- **制作工程**
制作の工程全体について述べます。
※本記事では、動画作成の工程のうち、キャラクター作画と背景作成（ComfyUIが関わる部分）を詳細に述べます。他の工程の詳細については別途記事にする予定です。
- **ComfyUIワークフローのダウンロード**
本記事の説明に用いるワークフローおよび入力データのサンプルを掲載しています。
適宜必要なファイルをダウンロードしてください。
- **ComfyUIによるキャラクター作画と背景作成**
AIに作画を任せている部分については大きく分けて、キャラクターと背景の２つあります。ここではそれぞれの作り方を順に、サンプルデータをもとに説明します。
- **Tips**
こういうときどうすればいいのかといった情報をまとめています。
- **問題点**
筆者がまだ未解決の問題を述べます。

# 制作工程

## 全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/1afe4da2-6eb7-aac0-2f53-2efd35fd32fd.png)

本制作の生成AI利用における特徴は二つあります。

- 生成AIへの入力データをできるだけ詳細にすることで狙った画を作ってもらうこと

特にキャラクター作画については、生成AIへの入力として3DCGデータを使用します。
デメリットはデータ量を増やすとなるとその分手間も増えることです。が、周辺のソフトウェアが充実しているので意外と簡単にデータ量を増やすことができます。以降では各ステップの説明と使ったソフトウェアも紹介します。

- 背景とキャラクターを別々にAIに作画させること

これはのちの撮影の工程で背景だけに処理をかけたい・動かしたい、キャラクターだけに処理をかけたい・動かしたいことが多々あるためです。

制作は大きく分けて4ステップです。個人で制作するので、業界の参考書を元に個人レベルで実施できる分量まで、圧縮・削減しています。

- **コンテ作成・背景作成**
何分何秒のときにどんな画にするか作品の設計図を作成します。同時にここでAIを活用し背景を作成していきます。
- **キャラクターデザイン・モデリング・モーション作成**
登場させるキャラクターを制作します。また、作品の設計図を基にキャラクターに演技させた動画データを作成します。
- **原画・動画・仕上**
動画データをAIに入力し手描き"風"のキャラクターを作画してもらいます。
- **音響効果・撮影・編集**
キャラクターの作画、背景を動画編集ソフトに取り込み、効果音・BGM・VFXを付けます。

また、本記事では制作工程のうちキャラクター作画と背景作成をのちに詳細に述べます。

## コンテ作成・背景作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/2193a0c4-767d-9056-d013-0bf2d572b5ac.png)
まずコンテ作成・背景作成を同時並行で行います。2ステップあります。
背景作成に関しては、[ComfyUIによるキャラクター作画と背景作成](#-ComfyUIによるキャラクター作画と背景作成)の項目で詳細を述べます。

**大まかなシナリオを書く**
ここではおおまかに動画全体の流れを文章で（必要があればラフ画も）書きます。
例えば、ストーリーの起承転結について大まかに何分何秒～何分何秒で起こるかそれぞれ書いていくイメージです。

**コンテ作成**
個人で作っているのでかなり雑です。主に書く内容は、カット（場面分けの最小単位）の秒数とその時の画面、内容を記載します。背景がどのように動くか、キャラクターがどんな動きをするかなど書いていきます。ここで用いる画面の素材は、コンテ用だけではなくそのまま背景の完成素材として用います。

## キャラクターデザイン・モデリング・モーション作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/9bf91069-84bf-ba1f-7075-61f375807ce9.png)
次に3DCGの制作に取り掛かります。3DCGの制作は大きく分けて3ステップです。
まず、キャラクターのデザイン・モデリングを行います。
次にキャラクターのモーションを作成していきます。自分で動きを演技しデータ化し、そのデータをブラッシュアップしAIに作画させるために動画データ化します。

**キャラクターデザイン・モデリング**
キャラクターのデザインを決めます。
筆者の場合、2次創作でありおおまかなデザインが決まっていたため、特にコツなど言えることはないです。。。
モデリング作業に関してはVroid Studioを用います。
Vroid Studioは直感的な操作感でありながら高いカスタマイズ性があるモデリングソフトです。基本のモデルを元に作りたいキャラクターへと各種パラメータの調整していきます。
また、衣装のデザインも自由に変更ができます。ただしVroid Studio内だけではデザインの制作が難しい場合もあります。（キャラクターに自作の杖や武器を持たせたいなど）その際は3DCGモデリングのソフトで別途作成する必要があります。
手早くやりたい場合Vroid Studioで再現できる範囲でデザインするのもアリだと思います。

**モーション作成 (動きを演技しデータ化)**
コンテでイメージしたキャラクターの動作を実際に3DCGのキャラクターに演技させます。ゼロから3DCGのボーンの動きを作成するのは大変なので、自分で動きを演技しそのデータをソフトウェア上でブラッシュアップします。自分で動きを演技しデータ化する手段としては、フルボディトラッキングの機器を用います。

有料
- Vive Tracker
- HaritoraX
- mocopi
など

無料
- Tree D Pose Tracker

有料の機器はどれも体に装着して動きをトラッキングしてくれます。
無料のTree D Pose Trackerについては、自分の姿を撮影した動画からトラッキングしてくれる素晴らしいソフトウェアです。
もちろん、有料の機器たちの方が圧倒的に精度が高いです。戦闘シーンを作るなら有料の機器が必須です。ここで精度よくトラッキングできると、のちのブラッシュアップの作業の負担が減ります。
まずは無料でできるTree D Pose Trackerを試してみて満足できなければ有料の機器に乗り換えるのがおすすめです。私はTree D Pose Trackerで制作を始めましたが、途中でブラッシュアップ作業の負担を減らしたいためmocopiに乗り換えました。

**モーション作成 (データをブラッシュアップし動画データ化)**
演技したデータを3DCG制作ソフトに取り込み、ブラッシュアップし動画データ化します。
3DCG制作ソフトといえば、BlenderやMaya、3DS MAXなどが思い当たりますが、私は今回Unityを選択しています。Unityはゲーム制作に適したソフトウェアですが、3DCGモデルのアニメーションを行うことも可能です。Unityを選択した理由としては、基本無料、直感的な操作ができる、コミュニティがでかく情報量が多いので初心者がとっつきやすいからです。ここでは、主にトラッキングが上手くいかなかったボーンの動作を修正し、コンテの画角に合うように演技しているキャラクターを録画します。


## 原画・動画・仕上
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/b9ef0daf-9832-e433-9966-bfa7baef8831.png)

キャラクターが演技している動画データを連番の画像データにしてAIに入力し、キャラクターの画を描いてもらいます。出力は動画時間分の枚数の連番の画像データとなります。描いてもらった画について気になる部分があれば手作業で修正します。

AI部分に関しては、Stable Diffusion (SD1.5)ベースのモデルを用いてComfyUIで処理を構築しています。
手作業の修正に関しては、Clip Studio Paint EXを使用します。

AI部分の詳細は[ComfyUIによるキャラクター作画と背景作成](#-ComfyUIによるキャラクター作画と背景作成)の項目で詳細を述べます。

## 音響効果・撮影・編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/fe634186-99a4-5f2e-7ac7-6370b4bb0ede.png)

キャラクターの作画と、コンテの際に作成した背景、BGMや効果音を動画編集ソフトに取り込み合成していきます。次にVFX（図中の光や煙など）も作成していき合成します。全て終わったら動画データとして書き出し、完成です。
筆者は動画合成・編集ソフトとしてAfter Effectsを使用しています。


# ComfyUIワークフローのダウンロード

別サイトに飛びます。(私のサイトです。)

https://seijatan.net/contents_download/

# ComfyUIによるキャラクター作画と背景作成

以降、前の項目のワークフローおよび入力データのサンプルを元に説明していきます。

## 動作確認環境

OS: Windows 11 Pro 23H2
CPU: AMD Ryzen 5 5600X
GPU: NVIDIA GeForce RTX 3060Ti (VRAM 8GB)
NVIDIAドライバーのバージョン: 546.33
CUDA: (Cuda compilation tools, release 11.8, V11.8.89)
cuDNN: (cudnn-windows-x86_64-8.5.0.96)

動作確認日: 2024/05/26

## 拡張ノードのインストール

以下、必要な拡張ノードです。ComfyUIを起動し、メニューの「Manager」→「Install Custom Nodes」からインストールしてください。

![拡張ノード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/1ee5660d-8c3b-89b4-9253-0f437e6e3ec2.jpeg)

## 各自で準備が必要なモデル

ワークフローを動作させるにあたり必要なモデルを記載します。各自ご準備ください。

### ComfyUI > models

**checkpoints**
Counterfeit-V3.0_fp32
flat2DAnimerge_v30

**controlnet**
control_sd15_seg
control_v11e_sd15_shuffle
control_v11f1e_sd15_tile
control_v11f1p_sd15_depth
control_v11p_sd15_canny
control_v11p_sd15_lineart
control_v11p_sd15_mlsd
control_v11p_sd15_openpose

**embeddings**
EasyNegative
verybadimagenegative_v1.3

**upscale_models**
RealESRGAN_x4plus_anime_6B

**VAE**
vae-ft-mse-840000-ema-pruned

### ComfyUI > custom_nodes > ComfyUI-AnimateDiff-Evolved
**model**
adStabilizedMotion_stabilizedMid


## キャラクター作画

ダウンロードしたZIPファイルを展開すると、下記のような構成となっています。
「char_sakuga.json」：ComfyUIのワークフロー
「char-sakuga-input」フォルダ内のmp4ファイル：本ワークフローの入力用のデータ
```plaintext
char_sakuga
    ├ char_sakuga.json
    └ char-sakuga-input
        ├ input_dwpose.mp4
        ├ input_lineart.mp4
        └ input_tile.mp4
```
char_sakuga.jsonをドラッグアンドドロップでComfyUIに読み込ませてください。

### ワークフローの説明

![char_sakuga_ワークフロー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/c7329d24-3bac-6a07-5550-45814906a808.jpeg)

上図の1~4の赤枠で囲ったエリアの説明をしていきます。
操作する箇所（1. 入力、2. ControlNetの調整）を重点的に説明します。

#### 1. 入力
![char_sakuga_ワークフロー_main_input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/c104c91c-840c-a529-84f8-b26c7bbf21de.jpeg)

① 動画データの入力

「char-sakuga-input」フォルダ内の各動画をそれぞれ入力します。
それぞれのノードのタイトル部に「Load Video (~)」と表記してありますので、それぞれに対応するMP4ファイルを割り当てます。ノード内下部の[choose video to upload]より動画ファイルをフロー内にアップロードすることができます。

また、右側上の「Empty Latent Image」では入力したMP4ファイルの縦横の幅を入力します。今回は、width=512、height=768のままでOKです。

また、その右側下の「EmptyImage」では、のちの出力ファイル作成用の白紙の画像を作成します。
width・height：入力ファイルの縦横幅を指定
batch_size：動画のフレーム数を指定
color：RGBカラーコードを指定
（**注意：16進数のカラーコードを10進数に変換する必要有**）
例えば、白色(#FFFFFF)の場合16777215となります。


② テキストプロンプトの入力


緑のノード最上段のテキスト入力欄は各フレームでどんな画にするかテキストで指定します。
```plaintext
"フレーム番号":"内容1",
"フレーム番号":"内容2",
...
"フレーム番号":"内容3"
```
なお、フレーム番号は0始まりなので注意。
「max_frames」はフレーム数を指定します。
中段(pre_text)および最下段(app_text)のテキスト入力欄については、フレーム全体にかかるプロンプトです。
ComfyUI_FizzNodesのREADMEには特に言及されてませんが、ソースコードを見たところ
- pre_text: 各フレームのテキストの前に追加するテキスト
- app_text: 各フレームのテキストの後に追加するテキスト

のようです。
また、「--neg」と記載した直後のテキストについてはnegative promptsとして取り扱うようです。

https://github.com/FizzleDorf/ComfyUI_FizzNodes/blob/main/BatchFuncs.py

赤色のノードはネガティブプロンプトを記述します。

下記記事の「B : まばたきしたり、笑ったりする！」の項目でも詳しく説明されていますので参照ください。
https://note.com/hanagasa_manya/n/n7fe5c448de30


#### 2. ControlNetの調整

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/cdf66099-e6ab-a4a2-4629-74aa719739ac.png)

ここでは、各フレームについて各種ControlNetのモデルの適用、およびその強度を調整します。本ワークフローでは左から、Lineart、DWPose、Tileのモデルを適用します。

上段黄色のノード「Latent Keyframe Group (~)」はモデルの適用強度をフレームごとに指定することができます。各フレームで柔軟に強度を設定したいためこのノードを用いています。
テキスト入力欄では個別のindex操作またはpythonスタイルの範囲指定が可能です。
https://github.com/Kosinkadink/ComfyUI-Advanced-ControlNet?tab=readme-ov-file#latent-keyframe-group
```plaintext
0=1.0, 1=1.0
```
や、
```plaintext
0:16=1.0
```
などで各フレームの強度が指定可能です。ちなみに強度の指定がないフレームについては"0"の強度となるようです。
各モデルの強度について本ワークフローでは基本的に、
Lineart:1.0
DWPose:1.0
Tile:0.8
で指定します。Tileのみ0.8としているのは、大まかな姿形は捉えつつ、細部の形状はある程度自由に描かせたいためです。体の各パーツの衣装のシワなどを表現してくれます。後ほど詳細を述べます。

#### 3. 生成

![char_sakuga_ワークフロー_生成.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/d94c0e64-6333-cfea-2030-2c6c1f331dfb.jpeg)

ここでは1.2.で設定した内容に基づいてAIが画を生成、背景を除去し、
出力結果を「ComfyUI > output > 年月日 > 時刻 > AnimateDiff」のフォルダ内に格納します。

1. 「KSampler」でAIが画像を生成します。
2. 生成した画像について、連番画像とGIF画像をrawフォルダに格納します。
3. 生成した画像の背景を除去し、その連番画像とGIF画像をraw-rembgフォルダに格納します。※raw-rembgのGIF画像は背景が白単色となっています。

#### 4. Upscale

![char_sakuga_ワークフロー_Upscale.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/8a766802-c3af-a635-d16f-5bdfa4b53d7f.jpeg)

ここでは前の工程で生成した画像をサイズアップします。
1. Upscaleします。
2. 前工程の処理と同様です。
3. 前工程の処理と同様です。


前の工程で生成した画像は縦横が512~768程度のサイズであり、そのままだと小さすぎるためサイズアップします。
筆者の動作確認環境では、動画生成に用いるには非力なPCのため拡大倍率は1.4倍に抑えています。もっとパワフルなPCをお持ちの方は、倍率を上げても良いかもしれません。
倍率を変更したい場合、①内「Upscale Image By」のscale_byの倍率を0.35から変更してください。
また、図中「※」のノードのscale_byの倍率も変更してください。
例: 1.4倍→2倍にしたい場合
①内「Upscale Image By」のscale_by = 0.5
「※」のノードのscale_by = 2

---

### 実行方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/d39215bb-05e0-5ff5-2cd6-e6c9d91f4fde.png)

Main Inputのノードグループ内のLoad Videoに動画をアップロードしてください。
それぞれのノードのタイトルに「Load Video (Tile)」のように表記してありますので、以下の3つのファイルそれぞれをノード内下部の[choose video to upload]より動画ファイルをフロー内にアップロードしてください。


![入力データ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/b9a588a4-460b-c48b-4134-8961e984d397.gif)

実行時間は4のみかなり掛かるので注意。
目安 (筆者環境 RTX 3060Ti VRAM 8GB)
- 1~3: 10分程度
- 4: 1時間程度

「3. Generator」までの処理でよい場合は、そのまま「Queue Prompt」を押して処理を開始させます。
「4. Upscaler」まで処理を走らせたい場合は、Upscalerのノードグループ左上のIMAGEノード(下図の黄色と黒色のノード)をつないでください。そのあと「Queue Prompt」を押して処理を開始させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/41b15e78-d733-62d5-2019-81ab76387672.png)

#### 出力結果

出力例を下図に示します。下図はUpscaleの倍率を2倍とし、フレーム数を36枚で実行した結果例です。

![出力結果.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/0cbdee9a-027f-d6f1-9de0-a86ea5d66a94.gif)

出力結果は下記フォルダに格納されます。
各フォルダに連番画像とGIF画像が出力されています。

```plaintext
ComfyUI
    └ output
        └ yyyymmdd
            └ hhmmss
                └ AnimateDiff
                    ├ raw
                    ├ raw-rembg
                    ├ upscaler-2x
                    └ upscaler-2x-rembg
```

---

### そもそも3DCGモデルのままでよくね？

ところで、3DCGモデルをただトレースするだけならAI画に変換したところで3DCG感が残ってまうやろ、わざわざAIに描き直させる手間をかけずに3DCGモデルのままでいいよ、と制作当初の私と同様に思われた方がいるかもしれません。が、そのままだと雑なテクスチャが目立つし3DCG感（というかVroid感）満載の画に仕上がるのでAI画に変換してみることにしました。

左：Vroidのまま使用　右：AI画を使用
![vroid-ai-比較.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/dc926739-ff53-bd94-4dca-98761c9ec237.gif)
※どちらも背景画になじむように同様の色補正を行っています。

いかがでしょうか？
定量的な比較はできていませんが、AI画の方を見ると、3DCGの画をトレースしているにも関わらず3DCG感が薄れてないでしょうか？
ちなみに3DCGと手描きの違いについて面白い考察があったので紹介します。
http://contradict.blog.bai.ne.jp/?eid=213094

> ３Dはポリゴンで板状の造形を作り、ボーンという支柱を設置します。
> そのボーンを軸として周りの板を引っ張って動かすのが３Dの基礎的な操作方法です。
> 一方手描きは一枚の絵を描きます。絵にも勿論、支柱（軸）を想定し、枠である絵を描いていきます。
> 手描きは軸と枠が機械的に分離しているため、どうやっても次の絵を描いた際に誤差が生じるのです。
> そして軟体的に描き分けて形状が大きく変化します。
> ３Dは機械的に軸と枠（ポリゴン）が結び付けられているため、とても綺麗に引っ張ってきます。
> この枠を引っ張る制作過程が、３Dと手描き２Dの根本的な壁ではないかと考えています。

3DCGからAI画に変換すると、大まかな姿形は抑えつつ細部の形状は3DCG側と比べてズレがある画に仕上がります（上記GIFで顕著なのが眉毛・スカート左側の腰から裾までのライン）。
この細部の形状のズレのおかげで3DCG感が薄れると筆者は考えているため、AIに作画してもらっています。

---

### 生成時のパラメータ調整や入力動画作成に関してのコツ

ここからは生成時のパラメータ調整や入力動画の作成に関するコツをまとめています。

#### TileとLineartのおすすめ強度

TileとLineartの強度はそれぞれ下記の範囲を目安に設定することをお勧めします。
- **Tile: 0.8-1.0**
- **Lineart: 0.5-1.0**

上記の設定であれば、大まかな姿形は捉えつつ細部の形状はある程度自由に（衣装のシワ等）表現してくれます。

以下TileとLineartの強度をそれぞれ0~1の範囲で少しずつ変えながら検証した結果です。
全フレームに同じ強度を設定しています。

Tile=1.0, Lineart=1.0, 0.8, 0.5, 0.2, 0.0
![t10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/004955c9-a97d-6381-e887-d78cf3820436.gif)
Tile=0.8, Lineart=1.0, 0.8, 0.5, 0.2, 0.0
![t08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/6d34ccf0-028c-7e62-730e-cf783eb33130.gif)
Tile=0.5, Lineart=1.0, 0.8, 0.5, 0.2, 0.0
![t05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/37cf4f35-3376-5d79-06fc-540ab7e0e3d9.gif)
Tile=0.2, Lineart=1.0, 0.8, 0.5, -, -
![t02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/988740e9-4886-4fbb-da84-4b8e85b10c7e.gif)

上図のように、Tileについて強度を下げていくと0.5-0.8ぐらいを目安に配色の制御が難しくなっていき、背景も賑やかになります。
また、Lineartの強度を下げていくと大まかな姿形が制御できなくなっていきます。わかりやすいのがキャラクターの角やスカートの矢印模様です。強度が低下するにつれて、角は形が変わり0.5付近から丸まってきて髪の一部分のように描画されています。スカートの矢印模様も0.2付近から曖昧に描画されています。また、上図のモーション例ではないですが、強度を下げていくと下図のように装飾（大腿部のバンドや腕輪）が増えてきたりします。

Tile=1.0,Lineart=0.5の例
![char_sakuga_lineart失敗例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/434bade8-55e3-1e0f-55eb-8baa2ebcdbdf.png)


#### Lineart：モデルとその背景をLineart専用に作成する

Lineart用のモデルはTile用のモデルを使いまわすのではなく、専用にモデルを作ることをお勧めします。
先ほどのサンプルのように、Tile用のモデルの衣装の色をすべて白色にし、色の境目に黒線を入れたモデルを作成すると、Lineartがくっきりします。また、背景もキャラクターの色からできるだけ離れた色相の色にします。サンプルでは緑色にしています。
以下、Tile用のモデルを流用した場合と、Lineart専用のモデルを使用した場合で生成結果を比較します。

(1-1) 入力動画にTile用のモデルを流用した場合（真ん中）
![char_sakuga_lineart検討1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/224607f8-78cc-5d7d-2934-a1cffc9dc99e.png)

(1-2) 左から、Tile、Lineart、DWPose、生成結果
![char_sakuga_lineart検討1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/7e26956a-ee6e-92cb-f8bf-121ba0e13596.png)

(2-1) 入力動画にLineart専用のモデルを使用した場合（真ん中）
![char_sakuga_lineart検討2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/1aa320c6-236d-a23c-a852-0e7b6150b9c9.png)

(2-2) 左から、Tile、Lineart、DWPose、生成結果
![char_sakuga_lineart検討2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/bdb977ed-a5e6-3cda-ba9c-8d9908b995a9.png)

各図の生成結果から分かるように、Lineart専用にモデルを作成した場合の方がより精確に色を付けることができます。
顕著なのがキャラクターのスカートの矢印模様です。(1-2)のLineartを見るとスカート部分がかなり薄れているのが分かります。その結果、生成される画像の矢印の模様も曖昧になってしまっています。


以下、背景に関しても比較します。なおキャラクターは両方ともTile用のモデルを用いています。

上段：背景白でLineartを実行した結果、下段：背景緑でLineartを実行した結果
![char_sakuga_lineart背景検討.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/9ba91f07-f28c-7ff9-29c9-11df2279cd80.jpeg)

なぜなのかわかりませんが、背景を緑にしてLineartを実行した方が、体の縁取りや頭部の各パーツの輪郭がはっきり抽出されます。

#### DWPose

- **DWPoseのキャラクターは足や手が良く見える衣装にした方が良い（半袖短パンなど）**

衣装がスカートのキャラクターで足回りが見えないなどの場合、高確率でポーズ推定が失敗します。

DWPose用のキャラクターでポーズ推定した結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/19d2305d-9a2b-a51b-b8d0-afeef3aacbaa.png)

Tile用のキャラクターでポーズ推定した結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/c9756437-67c8-392e-93ef-e185ba3e9815.png)

Tile用のキャラクターでポーズ推定した結果は、足がスカートに隠れる着地の際にポーズ推定が失敗しています。
一方でDWPose用のキャラクターでポーズ推定した結果、概ね良く推定できています。


- **色は上下とも肌の色から離れた色相の色を用いたほうが良い（？）**

2例しか検証していないため、説得力が欠けています。
肌色に近い色相の場合、ポーズ推定が失敗することがある？

白
![DWPose失敗例1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/0e470d0f-0983-c263-3990-2feded6b070f.png)

茶
![DWPose失敗例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/21567051-c239-7a41-c200-98bde3e7d031.png)

成功例
![DWPose成功例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/b7d26c68-cf05-3791-af15-4de158a50ccf.png)

HSV比較
|色名|H  |S  |V  |結果|
|:-:|:-:|:-:|:-:|:-:|
|肌 |26 |22 |98 | - |
|白 |25 |3  |94 | 一部失敗 |
|茶 |17 |36 |80 | 一部失敗 |
|黄 |52 |25 |98 | ○ |
|黒 |40 |12 |10 | ○ |

肌の色から離れたHueを使うといいかもしれないです。

- **できるだけ上を向いた姿勢で推定を行う**

下記失敗例を見ると分かりますが、上向きが推定しやすいです。
例えば、途中でモデルの上下がひっくり返るアニメーションのポーズ推定を行う際は、
上下ひっくり返した動画にもポーズ推定を行い、お互いうまく推定できているフレームのDWPose画像をマージするのがお勧めです。

![dwpose_向き_失敗例1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/d736ea2d-0161-f1d8-ca16-754cd1839b7a.png)

![dwpose_向き_失敗例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/1be538a3-a2d5-707d-2f21-b992c9acf229.png)

![dwpose_向き_失敗例3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/c5ae0e1e-42a7-7f82-d656-ba9d4c1273cf.png)

![dwpose_向き_失敗例4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/2c8d747c-4116-a2dd-50be-9417796ad594.png)

#### 入力動画の被写体の位置はTile,Lineart,DWPoseともピッタリ合わせる

DWPoseとLineartとTileの入力はスケールや被写体の位置を合わせておくことが大切です。
ズレていると被写体がブレて描画されたりするので注意してください。
特に**TileとLineartのそれぞれの3DCGモデルで揺れやすさの設定が少しでも異なると、動かした際に微妙にズレる**ので要注意です。

左からLineart画像、Tile画像、出力画像
![char_sakuga_ワークフロー_lineart_tile_ズレ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/c53a2f00-5daa-2edf-210d-75e91e9234e7.jpeg)

Tile用のモデルとLineart用のモデルの前髪部分の揺れやすさ設定が微妙に異なっていたため、
揺れ方に差が出たことで出力結果の前髪部分の描画が失敗しています。


## 背景作成

主に3つの方法で背景を作成しています。

- 静止画の場合
自作、画像素材の利用やAdobe Fireflyで画像生成し大雑把に画を作成する。
ComfyUIに入力し、背景画を作成。

- 背景を少し動かしたい場合
自作、画像素材の利用やAdobe Fireflyで画像生成し、Runway (Camera MotionやMotion Brush) で動きをつけて、ComfyUIに入力し画風を調整。例：制作動画2:19-2:21
例（ぱくたそ様よりお借りしたフリー素材）

https://www.pakutaso.com/20200653178post-28760.html

Adobe Firefly (生成塗りつぶしと生成拡張)で加工しRunway (Camera Motion)で動きをつけた背景
![bg_sakuga_runway_sample1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/ba134fd0-cf01-62a7-844b-341525b6c0d1.gif)


- 背景を激しく動かしたい場合
カメラを動かせるAI動画編集サービスで大胆に動かすのは厳しいので、3DCGソフトで動く背景を作成します。筆者はUnityで大雑把な背景動画を作成しComfyUIに入力しています。ただしフレーム数が多くなりがちなのでマシンパワーが必要な点には注意が必要です。激しく動く画をカクつき感なく滑らかに見せるためにはfpsを高めにして作成する必要があります。そのため、Google Colabで利用できるA100等、クラウドサービスでのパワフルなGPUの利用を推奨します。例：制作動画2:56-3:06、3:12-3:20
例。左：Unityで作成した大雑把な背景、右：ComfyUIの出力結果
![bg_sakuga_unity_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/4da942e9-cb20-772b-a651-756e1cd8c3ef.gif)

今回は静止画で背景を作るワークフローについて説明します。

ダウンロードしたZIPファイルを展開すると、下記のような構成となっています。
「bg_sakuga.json」：ComfyUIのワークフロー
「bg-sakuga-input」フォルダ内のpngファイル：本ワークフローの入力用のデータ
```plaintext
bg_sakuga
    ├ bg_sakuga.json
    └ bg-sakuga-input
        ├ input_bg.png
        └ input_bg_for_shuffle.jpg
```
「input_bg.png」は完成イメージを手描きで描いたものです（障子はFireflyで作成）。この画を元にAIに背景を作成してもらいます。「input_bg_for_shuffle.jpg」は出力画像の色味を調整するための画像です。例えば、カットが連続する場合に、前のカットと違和感なく色味を合わせて作成したい場合に、前カットの画像を使ったりします。

bg_sakuga.jsonをドラッグアンドドロップでComfyUIに読み込ませてください。

### 静止画の背景を作成するワークフローの説明

![bg_sakuga_ワークフロー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/ece3b3d5-5566-a47d-3b93-31772bb9155b.jpeg)

上図の1~4の赤枠で囲ったエリアの説明をしていきます。


#### 1. 入力
![bg_sakuga_ワークフロー_input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/22bc8553-006e-326b-7b1b-68ccb864f6a8.jpeg)

①画像の入力
上段は、深度情報取得・セグメンテーション・線画抽出を行うための入力です。ここで入力した画像が直接、画像の出力結果に影響します。下段は、出力結果の色味を調整するための画像です。

②テキストプロンプト
緑のノードのテキスト入力欄はどんな画にするかテキストで指定します。
赤のノードはネガティブプロンプトです。

#### 2. ControlNetの調整
![bg_sakuga_ワークフロー_controlnet.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/0a05c89e-21c5-af04-c9c4-efe88e536926.jpeg)

ここでは、各種ControlNetのモデル適用、およびその強度を調整します。

①Tile：入力画像の特徴を出力に適用します。
②Segmentation：入力画像に対してセグメンテーションを行い、（セグメントごとで色分けされます。色付けはランダムです。）出力画像に入力画像のセグメント情報を適用します。
③Depth：入力画像の奥行きの情報を出力画像に適用します。
④Shuffle：入力画像の色味を出力画像に適用します。
⑤Lineart(anime, realistic, standard)、M-LSD、Canny：入力画像の線画を出力画像に適用します。

①②③④は作りたい画に応じて強度を設定します。
⑤に関しては、各種線画抽出し、その中からどれか一つ気に入った結果のみ強度をいくらか設定し、他は強度0でよいかと思います。
強度は各ノード一番下の「Apply ControlNet (Advanced)」のstrengthで0-1の範囲で設定できます。

#### 3. 生成
![bg_sakuga_ワークフロー_generator.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/4fbf846e-5806-45c4-8241-98a858c71c68.jpeg)

ここでは、1.2.で設定した内容に基づいてAIが画を生成します。
出力結果は、「ComfyUI > output > 年月日 > 時刻 > Images」のフォルダに格納されます。
16枚生成されるので、気に入った画を選びます。

#### 4. Upscale
![bg_sakuga_ワークフロー_upscaler.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/90b3162d-5102-fefd-a38f-4813404d7bfe.jpeg)

前の工程で生成した画像を一つ選びサイズアップします。
前の工程で生成した画像は縦横が512~768程度のサイズであり、そのままだと小さすぎるためサイズアップします。
サンプルのワークフローでは2.6倍されます(およそFHDサイズ)。倍率を変更したい場合、「Upscale Image By」のscale_byの倍率を変更してください。

### 実行方法

Main Inputのノードグループ内のLoad Imageの[choose file to upload]より画像をアップロードしてください。
上段には「input_bg.png」ファイルを、下段には「input_bg_for_shuffle.jpg」ファイルを入力してください。

![bg_sakuga_実行方法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/383a577f-3707-3c8b-bcbd-eccd2c988622.png)

「Queue Prompt」を押して処理を走らせます。「3. 生成」まで完了すると、「ComfyUI > output > 年月日 > 時刻 > Images」のフォルダに16枚の画像が格納されます。

次に16枚の中から気に入った画像を選択し、Upscaleを行います。
「4. Upscaler」のIMAGEノード(下図の黄色と黒色のノード)をつないでください。また、Load Imageの[choose file to upload]より先ほどの16枚の中から気に入った画像をアップロードし、「Queue Prompt」を押して処理を続行させます。

![bg_sakuga_実行方法_upscale.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/1ef9cb0b-8bb8-d683-d04f-cd4a6616ff8e.png)

#### 出力結果

出力例を下図に示します。下図はUpscaleの倍率を2倍とした結果例です。
![bg_sakuga_出力結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/daaa5ba6-da1a-49d0-4c21-128e6b361de5.png)

出力結果は、「ComfyUI > output > 年月日 > 時刻」の「Images」と「Upscale-Image」のフォルダ内に出力されます。

---

### 背景作成に関してのコツ

ここからは背景作成に関するコツをまとめています。

#### 背景を1カットずつ作るのが大変
skyboxを作成すれば各カットで使い回せます(例：制作動画0:59-1:31の背景)。ただし、下記2点の注意が必要です。
- カメラが定点になってしまう
- 遠景なので使える状況は限られる

以下、作成方法を記載します。
参考記事：https://note.com/ri0m0ro/n/nbb9d4bbd4c00

![bg_sakuga_skybox1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/252c14c4-7c84-ac5a-3465-275ac56099e3.jpeg)

![bg_sakuga_skybox2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/e236a4bd-049f-022c-6c09-7c879690604c.jpeg)

①：Adobe Fireflyの「テキストから画像生成」で「seamless, 360 degree」の単語を含めて画を生成する。
②：画像編集ソフトで、画像を半分にし左右を入れ替える（真ん中で画が繋がっていない状態にする）。
③：Adobe Fireflyの「生成塗りつぶし」で真ん中を作り直し画を繋げる。
④：動画合成・編集ソフト上でVR素材として読み込む。

#### もう少し違うアングルの画が欲しい

難しいです。筆者は、カメラを動かせるAI動画編集サービス(Runwayのcamera-motion)を利用して無理やり動かしています。

(左)元の画像、(右)カメラを右上に移動した動画から取り出した画像
![bg_sakuga_カメラワーク.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/7948a662-2714-eddd-08e8-63ad3dcbd64e.jpeg)

元の画のスタイルが崩れてしまうので、あまり良いやり方ではないかもしれません。

#### 生成AIサービス間の品質差の均し方

複数の生成AIサービスを利用すると、画のスタイルがそれぞれ異なるため、同じ動画内で使うと違和感が出てしまうことがあります。そんな時は、ComfyUIのControlNetのTileで両方ともi2iすることで、画のスタイルをいくらか合わせることができます。

例：(左) Adobe Fireflyで生成した画、(右) Runwayで真横のアングルにした画
![bg_sakuga_品質差の均し方_before.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/67c0e13f-f5ff-08a5-e42d-f72eae1f9335.jpeg)

上図に対して、背景生成のワークフローを使いControlNetのTileを適用した画像
![bg_sakuga_品質差の均し方_after.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525427/6aa2d49a-61e6-2d42-f81d-0f61eb0a29b6.jpeg)

Strengthはできれば、0.8ぐらいが良いと思います（強くすればするほど元の画のスタイルが残る）。もし生成画の雰囲気が変わってしまう（例えば、天井からシャンデリアが新しく描きこまれてしまう等）のであればstrengthは強めにするなどしてください。線画強めのFirefly画と線画がボケてしまったRunway画が、両方とも程々の濃さの線画となり、画の雰囲気をある程度合わせることができたかと思います。


# Tips

こんな時どうするよといった記事を別で追加していきます。
リンクが並ぶ予定です。

# 問題点

今回制作した中でぶち当たった未解決の問題を挙げます。

**キャラクターの作画**

- バストショットやクロースアップショットの画を入力するとVroid感がにじみ出てくる。
- 絵を描くうえで見慣れない構図だと？(憶測) AI画が破綻する可能性が高まる。
記事冒頭の制作動画00:14や03:02付近のような飛んでる後ろ姿など。
（よく見ると足の作画が上手くいっていない）
- ポーズ推定が失敗するとAI画が破綻する可能性が高まる。
→DWPose人形(3DCG)が世にはすでにある？
- 細かい装飾の制御が難しい。（色味・形状両方）
制作動画01:46付近のキャラクターの背中の襟部分の矢印模様など。
- 表情の細かい制御。特に目線。表情は顔の小さな部分の微細な動作によって表される。
CGで丁寧に作り込んでも、AI画では正確に制御することが難しい。
制作動画02:11付近、弾が飛んでくる直前カメラをガン見しているが、
入力動画の3DCGではキャラクターは自分の手元を見ており、本来目線はもっと下に向けるはずだった。
- 体の部位のみのクロースアップショットは、AI画が破綻する可能性が高まる。
キャラクター目線で自分の体の腕だけ映るなど。制作動画01:20のキャラクターの右腕の肩付近の部分。
肩の袖が開いている衣装なので肌を見せたかったが、衣装が生成されており、手修正が困難なのでそのまま採用した。
- 細かい部分のrembgが失敗する。特に髪の間の背景が抜けないことが多い。
手作業で修正に時間がかかるし見落としも発生する。
- 遠目でのキャラクターの作画がどうすればいいかわからない。遠目の作画だからと言って、小さめに描いてもらうと作画が崩壊する。また、余白にいろいろなモノ（時には人物がもう一人）を描き足してくれる。
- 潰しや伸ばし。キャラクターの動きに合わせて誇張された伸び縮みをAI画で表現したい
- 床に落ちるキャラクターの影を作成する方法。現状、丸や三角で誤魔化している。

**背景**
- 光源位置の制御方法
- 通路など左右対称や単調な景色であれば、正面と後ろで比較的違和感ない画像を生成できる。一方で、室内で左右にいろいろな家具が配置されてるといったように対称性がなくなってくると、正面から見た空間とその真後ろの空間との一貫性のある画像を生成するのが難しい。
- キャラクターに纏わりつく煙や爆発などの表現

# おわりに

AI技術の進歩は早いので、（Soraが一般公開されたりすると）本記事もすぐ陳腐化すると思いますが、どんどん更新していきますのでよろしくお願いします。また、拙い表現で分かりづらい部分やもっと良い方法あるよと思った方は、指摘いただけると助かります。
今後も上記に挙げた問題点をなんとかできないか考えつつ、作品を上げていくのでよかったらチャンネル登録してね！


# 参考文献

**制作工程の参考図書**

神村 幸子. アニメーションの基礎知識大百科. グラフィック社, 2009, p.8-76
https://www.graphicsha.co.jp/detail.html?p=40427

吉邉 尚希. ショートアニメーション メイキング講座. 技術評論社, 2017, p.240-246
https://gihyo.jp/book/2022/978-4-297-12549-3

**ComfyUIワークフロー構築の参考サイト**

花笠万夜. "【ComfyUI + AnimateDiff】〜「私の生成したキャラが、いい感じに、動いてくれたらなぁ」を実現しよう〜". note. 2023-12-27. https://note.com/hanagasa_manya/n/n7fe5c448de30, (参照2024-01-31)