5
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Blenderと立体漫画のメモ

この記事は Blender Advent Calendar 2020 17日目の記事です。

「立体漫画」と言われる漫画は色々あるわけですが、最初の立体漫画(3-D Comic Book)は1953年にアメリカのKubertとMaurerによって作られたものだと言われています。
Mighty-new-anaglyph.gif
http://www.3dfilmarchive.com/home/images-from-the-archive/comic-books

この時代、日本でも雑誌の付録として立体漫画が作られたことがあるようですが、まとまった資料を見つけることはできませんでした。
まあそれはさておき。

以下ではBlenderを使って、ClipStudioで描いた漫画からこんな感じのアナグリフを作る方法について書いています。

本当はBlenderなんて使わずに、手作業でレイヤーを赤と青に複製して左右にずらすのが簡単なんですけど、ここは敢えてBlenderを使います。

アナグリフ以外にも対応できるようにしたいのです。

自分には「パララックスでぐりぐり動く立体漫画ビューアを作りたい(というか自分が使いたい)」という夢があるのですが、すぐには叶いそうにありません。立体原稿から立体ビューアまで全部一人で用意するのも大変なので、とりあえず前半の「立体原稿」の部分だけでも見通しをつけておこう、というのが今回のもう一つの狙いであります。

アドオンの概要

そうは言っても、Blenderは初心者なんで、アドオン書くのも今回が初めてですし、作りながら「これじゃダメだ」と気づくところも多々あったのですが、直す時間もありません。いろいろ残念な感じです。

サンプルも本当は自分で描けばいいのですが、時間もないのでセルシスのサイトにあるものを使わせて頂きました。

スクリーンショット.png

まずClipStudio上で、レイヤーを整理して高さ別にいくつかのグループに分けています。
マスクは3Dに変換できないので、コマ枠の外側は白に塗りつぶして誤魔化しました。ホールドアウトシェーダーとか使えばできるんだろうか。

ClipStudioから[複製を保存]で書き出したPSDファイルをimportして、各レイヤーを立体空間に並べて、カメラとか適当に設定して……というのが今回のアドオンの流れです。

スクリーンショット2.png

アドオンの基本は、丸写しですね。
こことかここを参考にしました。

bl_info = {
    "name": "Import PSD to 3D Comic",
    "description": "",
    "author": "funige",
    "version": (1, 0, 0),
    "blender": (2, 80, 0),
    "support": "TESTING",
    "category": "Import-Exoprt",
    "location": "File > Import > PSD to 3D Comic",
    "warning": "",
    "wiki_url": "",
}

import bpy
from bpy.props import StringProperty
from bpy_extras.io_utils import ImportHelper

class IMPORT_OT_psd_to_3dcomic(bpy.types.Operator, ImportHelper):
    bl_idname= "import_image.psd_to_3dcomic"
    bl_label = "Import PSD to 3D Comic"
    filename_ext = ".psd"
    filter_glob = StringProperty(default="*.psd", options={'HIDDEN'})

    def execute(self, context):
        path = self.properties.filepath

        # ここは後で
        print(path)
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

# -----------------------------------------------------------------------------
# Register

def menu_fn(self, context):
    self.layout.operator(IMPORT_OT_psd_to_3dcomic.bl_idname, text="PSD to 3D Comic")

classes = [
    IMPORT_OT_psd_to_3dcomic,
]

def register():
    bpy.types.TOPBAR_MT_file_import.append(menu_fn)
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    bpy.types.TOPBAR_MT_file_import.remove(menu_fn)
    for c in classes:
        bpy.utils.unregister_class(c)

if __name__ == "__main__":
    register()

以下でexecuteの中身を書いていきます。

PSDの読み込み

PSDの読み込みをアドオンで書いたのは……失敗でした。
うちのMacBookでは2分ぐらい固まってしまいます。python遅すぎです。

import os
from psd_tools import PSDImage
from bpy_extras.image_utils import load_image
...
    def execute(self, context):
        path = self.properties.filepath
        psd = PSDImage.open(path)
        for layer in psd:
            print(layer)

        # psdと同名のフォルダを作成
        basename = bpy.path.basename(path)
        self.dir = os.path.join(os.path.dirname(path), os.path.splitext(basename)[0])
        if not os.path.isdir(self.dir):
            os.makedirs(self.dir)

        # 各レイヤーをpngに出力
        self.names = {}
        y = 0
        for layer in reversed(psd):
            if layer.is_visible():
                image = self.create_layer_image(layer, directory)

        return {'FINISHED'}

    def create_layer_image(self, layer):
        texture_name = self.get_unique_name(layer.name) + ".png"
        layer.composite().save(os.path.join(self.dir, texture_name))
        return load_image(texture_name, self.dir, force_reload=True)

    def get_unique_name(self, name):
        if name in self.names:
            self.names[name] += 1
            return name + '.' + format(self.names[name], '0>3')
        else:
            self.names[name] = 0
            return name

psd_toolsを使っているので、別にインストールが必要です。
外部ライブラリをインストールする例
(Windows)https://bluebirdofoz.hatenablog.com/entry/2019/07/13/095606
(macOS)https://qiita.com/kjunichi/items/a36fdc9db3876e068249

こういう処理はアドオンにするより、fSPYみたいに外部ツールに分離して、テクスチャのパスとか座標だけアドオンに渡す形がいいのではないか、と思います。

レイヤーをカメラの前に配置する

ここが一番Blenderらしい処理だと思うのですが、残念ながら詳細は省略です。
きちんと仕上げたいのですが、時間がありません。年末なのです。
アドオンのコードはGitHubにあげましたので、興味がある人は見てください。
https://github.com/funige/3dcomic/tree/master/blender_addon
ほぼほぼ、Blender付属の Image as Planes プラグイン(io_import_as_plane.py)からの丸写しです。

sample.png

アドオンをインストールすると、[ファイル]->[インポート]に[PSD to 3D Comic]が追加されるので、適当なPSDを読み込んでください。
あとはF12でレンダリングするだけなのですが……なぜか全体に暗くレンダリングされることがあるようです。理由はよくわかりません。
新規に2D Animationを作成してimportすると正しい色でレンダリングされるので、設定が足りない感じですね。
カラーマネジメントの設定を追加しました。

補足

自作の立体化を考えている人のために、もうちょっとだけ。
2Dの原稿から立体漫画を作る方法としてもう一つ押さえておきたいのは、ディスプレースメントマップを使う方法です。
スクリーンショット3.png

スクリーンショット4.png

ポリゴンを増やす代わりにバンプマップとか使うのと似ていると言えば、似ているかもしれません。
Blenderならこれも簡単ですが、今後の研究課題としておきましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
5
Help us understand the problem. What are the problem?