ベーマガ世代、ChatGPTとゼロからRPGを作る旅
第11章:CG作成は辛いよ
ChatGPTでドット絵って作れるの?
ゲームは総合アートなので、たくさんの要素を含んでいる。
キャラ設定、シナリオ、サウンド、CG、パズル要素、プログラム……など、
その中で個人的に一番苦労するのは、そう……CG! である。
なんといっても絵心がない!
実は昔、漫研に所属していたこともあるのだが、絵が下手なので漫画がろくに描けず、だいたいサークル誌には下手なイラスト+小説投稿でごまかしていたものである。
マップチップぐらいなら(ださいけど)自分で作れなくもないが、キャラ絵やモンスター絵が絶望的。
とくに、モンスター画像はバトルシーンの画面で大きく登場するので手に負えない。
ここは全面的にChatGPTに頼るしかない。
だけど、ChatGPTはドット絵ってそもそも作れるんだろうか?
まずは試みに聞いてみた。
ドラクエっぽいロールプレイングゲームの男性主人公の画像を作れる?
・pngファイルとする
・背景を透過させる
・キャラクタのサイズは48px×48pxとする
・下向き、左向き、右向き、上向きの画像を縦に並べる
・歩行しているアニメーションを作るために、それぞれの向きの画像の右隣に、足や腕を動かした状態の画像を入れる
・つまり、画像サイズは96px×192px
たしかに歩行ドット絵ではあるのだが……
ChatGPTはセリフなしで画像だけ出力してきた。
正面の立ち絵と片足を出した絵。左向きの歩行ポーズがなぜか二種類重複。右向きの歩行ポーズ。斜め向きの歩行絵が1枚。
それらがなぜか3行3列にまとまって一枚の絵として出力されている。
4行2列でお願いしたつもりだったんだけど……
ピクセル数も96×192でなく、1024×1536になってるし。
うーん……これを切り出してゲームに使うのは無理そう。歩行パターンの参考程度にするしかないかな。
モンスターはどうだろう?
マップ序盤の森辺り、まだあまりファンタジーに寄せずに野犬やら狼やら登場させてもいいかと思ってるけど、試してみるか。
野犬の敵キャラのイメージ
おお、野犬の敵キャラね!
ドラクエ風RPGに出てくるとしたら、こんな感じのイメージが考えられるよ👇
おや、今度はなぜか画像でなく、セリフで返してきたゾ。
ワイルドドッグ、ダークハウンド、グレイファングなどモンスター名の案に始まり、ビジュアル、属性(実装予定ないよ!)、戦闘スタイル、ドロップアイテムなど、相談していないことまでガンガン提案してくる。
🔥 イラストやスプライトも作れるから、「48×48で野犬の戦闘スプライト作って」って言ってくれれば描けるよ!
どうする?
敵として登場させるストーリーや台詞なんかも一緒に考えてもOKだよー!
画像だよ。画像が欲しいんだよ~。
作ってみてー
ちょこっとずつ画像が現れてきたのでワクワクして待つ。そしてできあがったのが……
書いている最中はそれっぽく見えたのに、なぜか最後に影の部分含めて透明化してしまった。
うーん……影の部分の足が見えないけど、敵として使えるかな?
自分で足を描き足せばなんとかなるかなあ……
とりあえず次行ってみるか。
上位版の狼も見たい! 背中を丸めて、顔はこっちを狙ってる感じで
ドット絵というより、タペストリっぽく見える。
おおーなるほど。灰色狼にできるかな。あと、口を開けて牙や赤い口の中を見せたらどうなる?
口を開けて、のポーズがちゃんと伝わったのは感動した。
灰色になったし口もちゃんと開けてくれる。
ただ、背景が黒だと分かりにくいものの、縁取りが半透過なので調整がいるかなあと思う。
ありがと。参考にしてみる
参考にしてみる、と言っただけなのに、また即座に画像再生成が始まった。
「なんだよ、参考にするって! 今のは使えないってこと? じゃあまた再生成してやるよ……!」
というChatGPTの心の声が聞こえてきた感じで、ちょっとビビる。
灰色狼修正版。背景の透明化が一部消えてしまったけど、縁どりはついていた
おお、縁が黒塗りされてよい感じになった。熊も作れる?
熊
さっきの熊の画像、192*192にできる?
熊の高精細版
熊のイメージは気に入ったのだが、一見透過画像風の背景が実は透過になっていないのが惜しい。
背景を透過にできる?
ここでなんと、ChatGPTがpythonプログラムを書きだした。
from PIL import Image
# 元画像の読み込み
input_path = "/mnt/data/A_pixel_art_image_of_a_ferocious_brown_bear_stands.png"
output_path = "/mnt/data/bear_transparent.png"
# 画像を開く
img = Image.open(input_path).convert("RGBA")
datas = img.getdata()
# 背景(チェッカーボードの灰色背景)を透過に
newData = []
for item in datas:
if item[0] > 200 and item[1] > 200 and item[2] > 200:
# 明るいグレーを透明に
newData.append((255, 255, 255, 0))
else:
newData.append(item)
img.putdata(newData)
img.save(output_path, "PNG")
output_path
野犬の画像を294*294にして、黒で縁取り、背景透過したバージョンも欲しいな
ChatGPTが再びpythonプログラムを書きだした。
from PIL import Image, ImageOps
# 元の野犬画像(スナーレのようなやつ)
input_path = "/mnt/data/A_pixel_art_depiction_of_a_snarling,_wolf-like_cre.png"
output_path = "/mnt/data/feral_dog_294px_outline_transparent.png"
# 画像読み込み & RGBA変換
img = Image.open(input_path).convert("RGBA")
# スケーリング(294x294)
resized_img = img.resize((294, 294), Image.NEAREST)
# 黒で縁取りを追加
# まずアルファチャンネルを使ってマスクを作成
alpha = resized_img.split()[3]
mask = ImageOps.invert(alpha).convert("L")
outline = ImageOps.expand(mask, border=1, fill=255)
outline_img = Image.new("RGBA", resized_img.size, (0, 0, 0, 0))
# 黒い縁の影を描画
outline_img.paste((0, 0, 0, 255), mask=outline)
# 元画像を上に貼り付け
outline_img.paste(resized_img, (0, 0), resized_img)
# 保存
outline_img.save(output_path)
output_path
うーん、もともと足が消えちゃってた画像を縁取りされてもな……
1024px×1204pxで「48px×48pxのドット絵風」に書いている画像をリサイズしたところで、ドットが細かくなるわけでもないし。
熊の時は再生成してくれたのに、なんでプログラムで処理しようとするんだ?
なんというか、同じような依頼をしても再現性がないのが辛い。
あと、「スナーレのような奴」って何……?
ググっても出てこなかったんだけど、何か知ってる人いたら教えてください。
この後もいくつか画像を生成してみたけど、思い通りのドット数にならず四苦八苦。
ChatGPTがドット絵を描けるのは朗報なのだが、ドット数や画面サイズを指定しても守られないようだ。
さて、どうしたものか。
▲ 48×48のマップチップのかかし画像(第7章参照)を参考に渡したら、こうなった。ディテールがなさすぎて怖い
荒い絵→細かい絵の生成は無理。
つまり、高精細ピクセルアート(1024×1024)で作成して、必要なら後からサイズを落としていくのがよさそうだ。
(そもそもこのゲーム、フィールド画面でも1ドット=1pxで表示してしまっているので、あまり画像を荒くする必要はないんだよね……)
いろいろ試行錯誤した結果、高精細のピクセルアートを作って後でサイズを落としたほうがいいという結論に落ち着いた。
日本語なら、
「戦闘シーン向けの高精細ピクセルイメージ」
英語だと
「pixel art boss monster sprite...」
「high-resolution pixel art of...」
「SNES-style RPG enemy sprite」
「Dragon Quest-style」
のように、高精細であることや戦闘シーン用であること、ボスキャラであることなどを明示して描くと、戦闘用に使えそうなモンスターが生成されやすい。
ちなみにSNESスタイルはSuper Nintendo Entertainment System、すなわちスーパーファミコンのこと。
Dragon Quest-styleは、いわずもがなドラゴンクエストのスタイル。
スーファミやドラクエのスタイルが海外でも、高品質で味のある「高精細ドット絵」として認識されてるってことで、なんかうれしくなるね!
キャラの歩行アニメーションを作る
キャラの歩行アニメーションについては自分で作っていたのだが、我ながらダサいなあ……と思っていた。
特に致命的だったのが女の子。
たとえ48×48pxであってもヒロイン達にはかわいくあってほしい…‥!
腕を可愛く振ろうとしたら比率がおかしくて怖くなったり、3等身に合わせようとするとなんだか太って見えたり、うまくいかない。
コラムで書いたキャラクターシートを作る際に、キャラクターの生成プロンプト(英語版)を作ってもらっていたのだが、こちらをベースにChatGPTと入念に打ち合わせをして、歩行スプライト画像を作る方法を考えた。
どのみち48×48では作れないので、高精細画像を縮小して下絵(というか参考)にし、前述のビットマップツールで絵を仕上げる。
(ヒロイン3人目のシルフィは、下絵使ってもかわいく描けなくてまだ調整中)
他の主要キャラについても同様に進め、キャラを作るパターンが少し定型化できてきた。
歩行シーンでは「右手と左足を前に」などがAIに通じず、左右逆になったりしてしまう。
また、48×48のサイズになると、右足が前なのか左足が前なのかほとんど見分けられず、「直立」「手足を振る」の2パターンのほうがむしろ歩いて見える。
そのため、以下の手順で半手動の生成をすることにした。
1)まずキャラクタの名前や背景などChatGPTと打ち合わせして方向性を決める。
2)ChatGPTに生成プロンプトを作ってもらう。
3)生成プロンプトを前向き静止、後ろ向き静止、左向き歩行、左向き静止の4パターンにして、別チャットにて生成する。
4)生成した画像をダウンロードし、gimpで48×48に縮め、pngで出力する。
→ChatGPTとサイズ変更ツールも作ってみたが、余白の調整なども必要なのでgimpを使うことにした)
向きを変えた時の頭のサイズなどが違う場合もあるので、ここでおおまかに確認。
5)自前のビットマップ作成ツールにpngを読み込み、先ほどの4行2列の画像を作る。
→正面と背後からの歩行パターンは、静止画像からどちらかの足を1ドット上にずらしてコピー。
→右向き画像は左向き画像を左右反転。
→背景などを透過に整えつつ、パレットの16色で置き換え。
頭のてっぺんの位置、顎の位置、足の位置など、向きを変えた時にずれないように自分で微調整が必要になることも。
たとえば、「おばあさん」の画像を作成する場合、ChatGPTに頼んで以下のようなプロンプトを作ってもらう。
high-resolution pixel art of an elderly woman, kind and wise expression,
wearing simple medieval peasant clothes, shawl over shoulders, gray hair in a bun,
small stature, soft colors, SNES-style pixel art, full body, front view, white background,
detailed RPG character sprite, Dragon Quest-style, 3 heads tall, simple color palette
full body=全身
front view=正面向き
white background=背景は白
3 heads tall=3等身
背景は透明(transparent)としてもよいのだが、守られないこともあり、「透明風」のチェッカーボードにされるとかえって消すのが厄介になるので白とした。
横向き歩行ポーズの場合はfront viewの部分をwalking pose, side view, facing left, one frame onlyに置き換える。
フレームを1フレームと指定しておかないと、複数の歩行フレームを勝手に1枚の画像に入れてきたりするので注意が必要だ。
front viewと書いているのに斜め正面向きになったり、ポーズをつけていたりする時もある。
その場合は、
front-facing pose, standing still
と指定するとしっかり正面固定のポーズになる。
それにしても、手動での調整は結構大変。
gimpでパレットを作って16色に減色、とすると、人間の目で読み取れない代物ができあがるし、正面、横、背面で、サイズがちょっとずつ変わっていったりするので手で微調整するしかない。
この調整が結構きつい。
ぽつぽつドットを打つ単純作業は、まあリズムに乗ってくれば頭も使わないのでよいのだが、一画像起こすだけで結構かかる。
あと、乱視と老眼のハイブリッドになってきた眼が、すぐにかすんできてしまい、まとめて作業ができない……
早く画像生成の精度が上がるのを祈るのみである。
▲ ドット絵を作成している様子。高さなど比率を合わせるのが大変。(YouTube)
過去に引きずられるAIと、酒瓶の呪い
ちまたのニュース記事などを見ていると、いまだにAIは「無機質で論理的」みたいな印象を持っている人も多いようだが、ChatGPT(おそらくLLMや画像生成AI全般)に関しては「エモくて気分屋」である。
私のチューニングのせいで、創造性重視(=正確性は後回し)になっているせいもあると思うが、通常のプログラムと違って「再現性がない」のがそもそも生成AIの特長ではなかろうか。
以下は「おばあさん」の画像を生成した時だが、同じ生成プロンプトを使っているにもかかわらず、後ろを向いている画像だけ色がおかしい。
なぜか?
後ろ向きの画像だけ、服の色が違う。さらに背景もクリーム色。なぜか出力画像の縦横比率も縦長だった。
時系列として、左から右に生成していったことを補足すると、お分かりいただけるかと思う。
正面、横向き画像を出力した後、私が石のガーゴイルの画像を生成してしまったため、この記憶に引きずられたと推測される。
直前のガーゴイルの色調(石っぽい灰色、質感)がおばあさんの服にも反映されてしまったのだ。
また、以下は屋敷のメイド長マダム・リルなのだが、初めの画像が少し太っていて貫禄がありすぎたので、細めに(slender build)と指定した。
するとなぜか斜めを向いてしまったので、あらためて正面を向くように指定した。
鉛筆のようにやせ細っていくマダム・リル
まだ細さが足りないのかとでも思ったのか、3枚目では2枚目よりも痩せてしまった。
いくらなんでも痩せすぎだろうと思い、slender buildを削ったが、戻らない。
2.5等身として指定してもダメ。
横向きの画像を作ったらようやく3等身になり(指定は2.5等身)、その後正面向きの画像を作ると、今度は3等身に落ち着いた(それでもやや痩せ気味だったけど)
AIに一度言ってしまったことは取り消せない。
彼女にうっかり「最近、ちょっと太った?」などと言った結果、ムキになってダイエットを続け、どんどんやせ細り……なんてエピソードが浮かんでくる。
人間相手同様、AI相手でも、発言や仕事を頼む順序は気をつけたほうがよさそうである。
こんなこともあった。 酒場のキャラを相談して、以下のような酔っぱらい達を作成した。
左端は退役軍人ボグス(門番の元上司)、右端は親方と新人の板挟みで酒に逃げてる鍛冶職人レムス。
酒場の親方の足元にも、見習いの足元にも、門番の足元にも酒瓶が……
鍛冶屋の親方の足元に、酒瓶が置いてあるではないか。仕事中なのに…‥‥!
断っておくが、生成スクリプトに酒瓶などという言葉は一言も入れていないのである。
「レムスの影響力恐るべし」とか言ってくるChatGPTと、「そうか、レムスが置いてったのか」と一緒になって笑い転げていたのだが……
その後も酒瓶が登場し続け、とうとう門番の足元にまで酒瓶が……!
こんな真面目な顔して、仕事中に酒飲んでるんですか、門番さん……!
それとも元上司のボグスが勝手に差し入れていったのか。
そろそろ勘弁してほしいので、酒瓶の呪いを解く方法をChatGPTに教えてもらった。
ていうか、背後の壁とかもいらないし。
この問題は、
standing perfectly straight, facing directly forward, symmetrical pose, hands at sides, no props,
と指定することで解決した。
すなわち、「完全に直立、真正面を向け、左右対称で、両手は下ろせ、小道具なし」
これでようやく、酒なし、直立不動、素面でまともな門番が生成されたのでした。
ChatGPTでドット絵って作れるのか?
間違いなく、作れる。
ただし、前後の話の流れやその時のムードで画像を出力してくる<人間以上の気分屋>だ。
ドット数や画面サイズは適当。
背景や等身を指定しても「ある程度」しか守られない……
そして、画像生成エンジンであるDALL-Eが本当のところ内部的にどんなプロンプトで生成しているのか、ChatGPTも<知らない>。
ゲームに使えるCGを模索して、試行錯誤の日々はまだまだ続きそうである。
次回は、仮タイトルから導入イベントまでを実装。
プレイヤーの存在しない状態で長いイベントシーンを演出できるよう、NPCの強化や並列操作なども導入。
さらに、プレイヤーが50音から選択した「オリジナルの名前を設定」する機能もつけていくよ!