ネコガネ:メモ帳

Adobe Flash & AIR、Action Script 関連とゲーム制作に関するメモ。

Blender&Photoshopで少しだけ楽にゲーム・アニメ系キャラクターモデルの肌テクスチャを作成する方法

Blender Advent Calendar 2014 12月5日の記事です。

Blenderは10月頃から触り始めて2ヶ月ちょいですが、自分なりにこう作ると楽かも?という方法ができてきたのでまとめてみようと思いAdvent Calendarに表明しました。

今回紹介するのは、ゲームやアニメ系キャラクターで表現されるような、グラデーションの肌テクスチャを作成する方法です。

テクスチャ作成方法の説明に入るその前に、初めてBlenderを使用して作った作品についても紹介させていただきます。


これは、ニコニ立体の3DCGコンテストのローポリ部門に応募したものです。

以前描いたイラストをベースに、3DCGのキャラクターとしてリメイクしました。

モデルにはRigifyのアドオンを使ってアーマチュアを作成し、ボーンやウェイトを設定してあるので自由にポーズを取らせることができます。

手の指まで稼働するように分割も多めに作っているので、あまりローポリとは言えない出来栄えです(^^;

と、色々書いてると話が脱線しそうなので、さっそく本題に入ろうと思います。

目次

  • Blenderでテクスチャに陰影をベイク(焼付け)する
  • Photoshopのグラデーションマップを使って色をつける
  • Blenderでオブジェクトにテクスチャを反映する
  • まとめ

Blenderでテクスチャに陰影をベイク(焼付け)する

初作品を作った時に、体や髪の毛のテクスチャをすべて3Dビュー上のテクスチャペイントでチマチマと陰影を描き込んでいたのですが、非常に時間がかかりました。 でも、テクスチャにレンダリング結果を焼きこむことができる「ベイク」という機能を使えば、簡単に3Dモデルの陰影を2Dテクスチャとして展開することがきます。 初めに、テクスチャにグレースケールの陰影をベイクする方法を紹介します。

陰影をベイクするための画像を作成する

  1. このようなUVマップを展開済みのモデルを用意します。 テクスチャを作成したいオブジェクトの編集モードに入り、キーボードの[A]キーを押して全てのメッシュを選択します。ここでは肌の陰影を作成するので、[Body]オブジェクトのメッシュを選択しています。

    f:id:necogane:20141205185434p:plain

  2. ベイクを行うための画像を用意します。 UV/画像・エディターで、[新規]ボタンを押して新規画像を作成します。 名前はベイク用の画像だとわかるように[bake_body]とか、幅と高さはお好みのサイズで、背景はとりあえず[黒(#000000)]に設定します。

    f:id:necogane:20141205185445p:plain

ライトを追加する

テクスチャに陰影をベイクするためには、陰影を表現するためのライトが必要です。 一般的?に陰影をテクスチャにベイクする時にはAO(アンビエントオクルージョン)を使用して影を落とすようなのですが、ここでは簡単に「ヘミライト」を使います。 表現したい絵作りによってライティング方法は変わってくると思いますので、各自色々試してみてください。

  1. 3Dビューのシェーディングをライトが反映される設定([テクスチャ]や[マテリアル])に設定します。

  2. [ヘミライト]を作成します。

    f:id:necogane:20141205185333p:plain

  3. このようにライトの位置を調整し、真上から光が当たって、脇の下などが暗くなるように配置します。

    f:id:necogane:20141205185245p:plain

ベイクする

  1. アウトライナー・エディターでベイクの元とするオブジェクトを選択します。ここでは肌の陰影を作成するので、[Body]オブジェクトを選択しています。

    f:id:necogane:20141205185548p:plain

  2. プロパティ・エディターのヘッダーにある[レンダー]ボタンをクリックしてオンにします。

  3. 下の方にスクロールして[ベイク]パネルを表示します。

  4. 下記のように設定をして、[ベイク]ボタンをクリックします。

    f:id:necogane:20141205185918p:plain

    • ベイクモード: [フルレンダー]
    • [クリア]にチェックを入れると、画像を消去してから描き込まれます。追加で書き込みを行う場合はチェックを外す。
    • [余白]は8~16pxぐらい。UVの同士の間隔に合わせて調整する。
    • [選択→アクティブ]のチェックを外す。
  5. 先ほど作成した画像に、陰影がベイクされました。

    f:id:necogane:20141205185828p:plain

  6. 画像を保存します。

    f:id:necogane:20141205185853p:plain

注意:ベイクするオブジェクトのマテリアルについて

ベイクモードの[フルレンダー]は、すべてのレンダリング結果を反映するものなので、選択したオブジェクトにマテリアルやテクスチャが設定してあると、その結果(色や模様)も含めて反映されます。 今回の作例では、グレースケールの陰影のみを使いたいので、マテリアルは何も設定せずデフォルトのママにしてあります。 もし、マテリアルを設定している場合は、一時的にマテリアルを外したり、グレースケールの陰影が表現できるマテリアルに切り替えてからベイクしてください。

Photoshopでグラデーションマップを使って色をつける

「グラデーションマップ」という機能を使って、肌色のテクスチャを作成します。

グラデーションマップってどんな機能?

画像の明暗の値を元に、指定したグラデーションの色に置き換える機能です。

f:id:necogane:20141205190249p:plain

f:id:necogane:20141205190257p:plain

もっと詳しく知りたい方は、以下の記事が参考になると思います。

グラデーションマップを作成する

  1. 保存した画像をPhotoshopで開きます。カラーモードが[RGB カラー]になっていることを確認します。

    f:id:necogane:20141205190334p:plain

  2. [レイヤー]パネルの下部にある[調整レイヤーを新規作成]ボタンをクリックし、表示されたリストから[グラデーションマップ]を選択します。

    f:id:necogane:20141205190354p:plain

  3. [レイヤー]パネルに調整レイヤーの[グラデーションマップ 1]が追加されました。

    f:id:necogane:20141205190407p:plain

グラデーションエディターを使って肌色を作成する

  1. [属性]パネルの[グラデーション]をクリックして、[グラデーションエディター]を表示します。

    f:id:necogane:20141205190435p:plain

  2. グラデーションは左端(位置0%)から右端(位置100%)に向かって、画像の暗いところから明るいところと置き換えます。現在は、左端に[黒(RGB:0,0,0)]右端に[白(RGB:255,255,255)]の2色が設定されています。

    f:id:necogane:20141205190446p:plain

  3. 位置を追加してこのような肌色のグラデーションを作成します。

    f:id:necogane:20141205190502p:plain

    • 左端(位置0%):RGB(214,192,85)
    • 左端(位置33%):RGB(245,169,96)
    • 左端(位置67%):RGB(255,255,200)
    • 左端(位置100%):RGB(245,248,229)
  4. [OK]ボタンを押して確定します。

  5. グラデーションマップが設定され、肌色のテクスチャが作成できました。

    f:id:necogane:20141205190536p:plain

  6. PNG形式などBlenderが読み込める形式で保存します。肌のテクスチャも後で色を調整できるようにPSD形式のファイルとして保存しておきます。

ポイント:グラデーションの色を選ぶときに

肌色で暗くなっている部分の色を選択する際、暗いからといって彩度の低い色を選んでしまうと肌の色がくすんでしまい、見栄えが悪くなってしまいます。黒を混ぜたような影色にならないよう、色の彩度に注意して選択するとよいでしょう。

Blenderでオブジェクトに肌のテクスチャを反映する

オブジェクトにマテリアルを設定して、肌のテクスチャを反映しましょう。

  1. アウトライナー・エディターでベイクの元とするオブジェクトを選択します。ここでは肌のマテリアルを作成するので、[Body]オブジェクトを選択しています。

    f:id:necogane:20141205185548p:plain

  2. プロパティ・エディターのヘッダーにある[マテリアル]ボタンをクリックしてオンにします。

  3. [新規]ボタンを押して、マテリアルを作成します。

    f:id:necogane:20141205191020p:plain

  4. マテリアルに「Skin.Body」という名前をつけました。

    f:id:necogane:20141205191033p:plain

  5. 今回は確認のため、ライトの影響を受け無いように[シェーディング]パネルの[陰影なし]にチェックを入れます。

  6. プロパティ・エディターのヘッダーにある[テクスチャ]ボタンをクリックしてオンにします。

    f:id:necogane:20141205191051p:plain

  7. [新規]ボタンを押して、テクスチャを作成します。

    f:id:necogane:20141205191101p:plain

  8. テクスチャに「Texture_Body」という名前をつけました。

  9. [画像]パネルの[開く]ボタンから、先ほど作成したテクスチャを読み込みます。

  10. 下の方にスクロールして[マッピング]パネルを表示します。

  11. 下記のように設定して、マッピングにUVマップが反映されるようにします。

    f:id:necogane:20141205191116p:plain

    • 座標:[UV]
    • マップ:[UVMap]※オブジェクトに関連づけられているUVマップの名称を選択してください。
  12. オブジェクトに肌のテクスチャが反映されました。

    f:id:necogane:20141205191142p:plain

f:id:necogane:20141205191147p:plain

まとめ

ここまで読んでくださった方の中には、「わざわざPhotoshopでグラデーションマップなんか使わなくても、ディフューズにカラーランプを使用してやればマテリアルだけで同じことできるじゃん」と思われるかもしれません。

より良いテクスチャに仕上げるにはここからが大事なところで、首の部分にはもっと濃い影を描き込んだり、膝や肘などには赤みを足してあげたり、胸などもっと立体感を強調したいところにはテクスチャにもライティング処理を加える必要があります。

応用編として、グラデーションマップの利点やテクスチャの書き込み方法についてもう少し掘り下げた話なども考えてたのですが、記事が長くなってしまったので、今後別記事として投稿しようと思います。

最後までお読みいただきありがとうございました。

明日のBlender Advent Calendar 2014は、kozmofさん「なんかテクニカルなこと(未定)を書きます」です。

よろしくどうぞー!

LINEスタンプ「モコとくろすけ」販売開始しました!!

f:id:necogane:20140610134550p:plain

長い審査期間を終え、「モコ と くろすけ」ようやく販売開始となりました!

スコティッシュフォールドの女の子「モコ」と黒猫の男の子「くろすけ」のスタンプです。

他の猫系スタンプとの違いは、カップル向けのLOVEな要素が少〜し入っていることです! もし、気に入っていただけましたら、あなたのパートナーと一緒に使っていただけたら嬉しいです。

評判がよければ…各キャラクター単体で、色んなシチュエーションメッセージを 増やしたバージョンも作成したいと思っています。

(13/12/06 更新) 指定したラベルにタイムラインヘッダを移動するFlashの拡張機能

指定したラベルにタイムラインヘッダを移動するFlash Proの拡張機能を作成しました。

この拡張機能のアイデアは、A.e.Suckさまの記事で、

AmazingFlash: 拡張コマンド ベスト3

沖くん作でフレーム番号を指定して再生ヘッドを移動するコマンドがあるんですが、これのラベル版があったらいいなあ。名付けて「ラベル名を指定して再生ヘッドを移動する」コマンド。

という発言をみつけたため。とても便利そうなJSFLなので、勉強がてら作ってみました。

…が、タイムラインが数百フレーム以上になるとヘッダが移動するまでに少し時間がかかりますorz
表示しているタイムラインのヘッダを動かすだけなので、シーンまたいだ移動もできません
そんなこんなで、いまいち実用性に乏しい拡張機能なのですが、とりあえず作ったのでひっそり公開して見ようと思います。

(2013/12/06 追記)
コードの最適化を行い、タイムラインのフレーム数が多くてもタイムラインヘッダの移動に時間がかからなくなりました。
修正バージョンは下記にアップロードしました。

ダウンロード

機能説明

  • 現在表示中のタイムラインのヘッダを、指定したラベルの位置に移動します。ムービークリップを表示中であれば、そのムービークリップのタイムラインヘッダを移動します。
  • ラベル名が重複していた場合は、最初に見つかったフレームラベルの位置にヘッダを移動します。

動作環境

  • Adobe Flash CS6 以降(Windows/Mac)
  • Mac OS X 10.7.5、Adobe Flash CS6、Adobe Flash CC で動作確認を行っています。
    たぶんWindowsでも動くと思いますが、インストールできなかったり、動かなかったりした場合は @necogane まで教えてください。

使い方

  1. Extension Manager を使用して、[goto_label_v1.1.0.zxp]をインストールします。
  2. [コマンド]メニュー→[指定ラベルに移動]を選択します。
    f:id:necogane:20131205170341p:plain
  3. [フレームラベル]に移動したいラベル名を入力し、[OK]ボタンをクリックします。 f:id:necogane:20131205170345p:plain
  4. タイムラインヘッダが指定したフレームラベルの位置に移動します。 f:id:necogane:20131205170349p:plain

注意

  • フレーム数が多い(500フレーム以上の場合)と、ヘッダを移動するまでに少し待たされます。 速度の改善策がないか検討します。→改善しました。
  • ラベル用のレイヤーは、なるべく一番上に置いておいてください。
    f:id:necogane:20131205175952p:plain
    これは、内部的に各レイヤーのキーフレームごとにラベルのチェックを行っているのですが、レイヤーは上から順番に検索しています。そのため、一番上にラベルレイヤーを置いておくと、一番初めにチェックが行われるので、ラベルの位置の検索処理に時間がかからなくなります。
    逆にキーフレームが沢山(500〜)振ってあるレイヤーが一番上に置かれていると、待ち時間がかかってしまいますのでご注意ください。

SFWデータの暗号化に関すること

ゲームのリソースデータの暗号化、複合方法を調べていて、データを暗号化し複合することはできたけど、肝心の秘密鍵をどこに持たせれば良いのか悩んでいた。
SWF自体に秘密鍵を含めてしまうと、仮にSWFを逆コンパイルされてしまった場合にバレバレになってしまう。

情報を探していたところ、SWFデータの暗号化に関することが、Adobeのページに掲載されていた。

より安全なSWF Webアプリケーションの作成 | Adobe Developer Connection

開発者はSWFファイルが逆コンパイルできることを認識しておく必要があります。このため、これらの暗号化方式の秘密鍵およびプライベート鍵は、SWFファイル自体の中に格納できません。少なくとも、対称方式の秘密鍵と非対称方式のプライベート鍵は、セキュリティで保護されたインターネットプロトコルを通じてダウンロードするか、エンドユーザのマシン上のSWFから生成することによって、漏洩を防止する必要があります。

引用箇所を更に抜粋すると、下記の2つの方法があるということだった。

  • セキュリティで保護されたインターネットプロトコルを通じてダウンロードする
  • エンドユーザのマシン上のSWFから生成する

ただ、インターネットに接続できない場合もあると思うので、他にも方法がないか探してみる。

ActionScript 3.0 で、ディスプレイオブジェクトからBitmapDataを取得するには?

インスタンス化したMovieClipなどのDisplayObjectからBitmapDataを取得するには、draw (BitmapData.draw メソッド)を使用する。 その際、matrixにDisplayObjectのスケール情報を渡すことで、変形後のBitmapDataを得ることが出来る。

flash on 2013-11-21 - wonderfl build flash online

package {
    import flash.display.Bitmap;
    import flash.geom.Matrix;
    import flash.display.BitmapData;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            
            //DisplayObject を作成
            var _mc:MovieClip = new MovieClip();
            _mc.graphics.beginFill(0xFF0000);
            _mc.graphics.drawRect(0,0,24,24);
            _mc.graphics.endFill();
            
            //[1]テストのためスケールを2倍にする
            _mc.scaleX = 2;
            _mc.scaleY = 2;
            
            //DisplayObject と同じサイズの BitmapData を作成
            //ビットマップデータ1
            var _bitmapData1:BitmapData = new BitmapData(_mc.width,_mc.height,false);
            //ビットマップデータ2
            var _bitmapData2:BitmapData = new BitmapData(_mc.width,_mc.height,false);
            
            //DisplayObject のスケール情報を取得
            var _matrix:Matrix = new Matrix();
            _matrix.scale(_mc.scaleX,_mc.scaleY);
            
            //BitmapData に書き込み
            //[2]ビットマップデータ1はそのまま
            _bitmapData1.draw(_mc);
            //[3]ビットマップデータ2には、Matrixを渡す
            _bitmapData2.draw(_mc,_matrix);
            
            //[4]ビットマップデータ1の方は、[1]のスケールが反映されず作成時の DisplayObject のサイズのまま
            var bitmap1:Bitmap = new Bitmap(_bitmapData1);
            this.addChild(bitmap1);
            
            //[5]ビットマップデータ2の方は、[1]のスケールが反映され2倍の大きさで表示される
            var bitmap2:Bitmap = new Bitmap(_bitmapData2);
            bitmap2.x = 48;//位置調整
            this.addChild(bitmap2);

        }
    }
}

ActionScript 3.0 でString型の内部文字コードは?

「UTF-16BE」(BEはビックエディアン)。
Adobe Flash Platform * データ型の「String データ型」にも書かれていて、charCodeAtで文字コードを調べるとUTF-16BE形式で文字コードが返ってくる。
(charCodeAt はUnicode表と照らし合わせるときにわかりやすい。)

外部読み込みするテキストファイル自体の文字コードは「UTF-8」が推奨とされているため、ByteArrayを使い自前でテキストファイルの文字コードを調べた時と、charCodeAtで調べた文字コードとの違いがややこしかったのでメモ。

はてなブログでSWFファイルの埋め込みテスト

DropBoxの[Public]フォルダを使用して、SWFファイルを表示。 [Public]フォルダ機能の復活は、下記リンクを参考にさせていただいた。感謝。

シケモク Tech: Dropboxで廃止されたPublicフォルダ機能を5秒で復活させる方法

Flash Player 11.7.0 以上をインストールしてください。