【Blender/Unity】SmoothnessマップをBlenderでアルファチャンネルに割り当てる方法:Channel Packing

blender
記事内に広告が含まれています。

Unityの Standard シェーダーでマテリアルを作っていると、Roughness(ラフネス)マップを設定する項目がないことに気づきました。

調べてみると、Unity では Roughness を直接使わず、Smoothness(Roughnessを反転した値)を、テクスチャのアルファチャンネルに割り当てるという仕様になっているようです。

ブログ記事などを見ると Photoshop でマップを作成している方も多いですが、Photoshop を持っていなかったり、わざわざ使うのはめんどい。

そこでこの記事では、Blenderだけを使ってSmoothness マップをアルファチャンネルに割り当てたテクスチャを作成する方法を解説します。

ちなみに、RGBA などのチャンネルに複数のテクスチャマップを割り当てて1枚のテクスチャを作成する手法は
Channel Packing(チャンネルパッキング) と呼ばれ、ゲームエンジンではよく使われています。

この方法を使えば、Blenderでゲーム用のテクスチャをチャンネルパッキングできるようになりますので、ぜひ参考にしてみてください。

この記事は、Blenderでアルファチャンネルにテクスチャを割り当てる方法を解説している初級~中級者向けの記事です。

難易度 2.0

スポンサーリンク

Standard ShaderのSmoothnessマップ

例えば右図のように、Blenderで赤青チェック柄の床を作り、青い部分だけRoughnessを下げてつるつるにしたマテリアルを作ります。

これをUnityに持って行ってStandard シェーダーで再現しようと思うんですが、Roughnessマップをつける項目がありません。

Unity Standard シェーダー では Roughness マップを直接指定する項目がなく、代わりに Smoothness(= 1 − Roughness ラフネスの反転) を使用します。

よく見るとSmoothnessの下にSourceという項目があり、

  • Metallic Alpha…MetallicマップのアルファをSmoothnessマップとして使う
  • Albedo Alpha…Albedo(カラー)マップのアルファをSmoothnessマップとして使う

のどちらにするか選ぶことができます。

シェーダーで使うテクスチャマップを削減するため、Smoothnessマップを別のRGBマップのAチャンネルにつけてしまうという方式らしいです。

どちらを使ってもいいので、空いてるアルファがある方のテクスチャにSmoothness マップをつけてしまいましょう。

※Albedo のアルファを透明表現に使うマテリアルでは、
Smoothness は Metallic のアルファを使う必要があります。

Unityの Standard シェーダーでは Roughness マップを直接使わず、Smoothness(Roughnessを反転した値)を
Metallic もしくは Albedo のアルファチャンネルに格納します。

スポンサーリンク

アルファチャンネルに別の白黒マップを割り当てる方法

テクスチャのアルファチャンネルに別のマップを割り当てるのは、Photoshopなど外部のペイントソフトなどで編集して作ることもできますが、今回はBlenderのコンポジット機能を使ってやってみます。

今回はAlbedoのアルファにSmoothness マップを付けます。(同様の方法でMetallicのアルファに付けることもできます。)

Blenderでは、カラーのテクスチャ出力をRGB, ラフネスの出力を反転してA(アルファ)につけてunityに持っていきます。

●まずカラー(Diffuse)、ラフネスなどのテクスチャはベイクしておいてください。(アルファにつける場合はラフネスの解像度をカラーの解像度に合わせておいてください。)

●Color ManagementでViewをStandardにします。

Compositorエディタを開き、Imageノードでカラーとラフネスを出します(ラフネスの方はColor SpaceNon-Colorにしてください)

Separata ColorCombine Colorノードを出して、カラーのImage出力をRGB, ラフネスの出力をAlphaに割り当ててOutputやViewerノードに接続します。

このとき、ラフネスのImage出力にInvert Colorノードを出して反転してください。

Imageエディタでプレビューを見れます。画面右上にDisplay Channelsという、チャンネルごとの画像が見れるメニューがあるので、そこでColor, Alphaを見てチェックしてみてください。

(この接続でうまくいきましたが、もしColor出力も透過されていたら、Alpha ConvertノードをTo Straightモードにして最後に接続してみてください。)

Alphaにラフネスの反転の白黒画像、Colorにカラーのテクスチャ画像が見えていればOKです。

出力

Outputプロパティで解像度のサイズをテクスチャのサイズにしてレンダリングします。

レンダリング画像を保存するときはRGBAになっているか確認してください。

ちなみにこれで出力した画像はPC上では透過画像に見えることがあります。それでも内部ではきちんとRGBの値を持っています。
本当にRGBに値が入っているのか心配な場合は、これもCompositorエディタにImageノードで出してみてDisplay Channelsで確認してみてください。(このときImageノードのAlphaはChannel Packedにしておいてください)

スポンサーリンク

Unityで使ってみる

出力したテクスチャをUnityで使ってみます。

アルファにSmoothnessマップを割り当てたテクスチャをAssetにドラッグ&ドロップして、マテリアルのAlbedoに設定します。

Smoothness SourceがAlbedo Alphaになっているか確認します。

設定してみると、実際チェックの青い部分にだけ光が反射しています。狙った通りにSmoothnessが効いています。

スポンサーリンク

アルファにベイクはできないのか?

こんなことしなくても、普通にアルファつきのカラーでベイクできないのか?と思うかもしれません。自分もそう思いいろいろやってみましたがうまくいきませんでした。

Blenderでは、画像や合成処理の内部でPremultiplied(プリマルチプライド)方式が前提になっており、アルファが 0 のピクセルでは、たとえ RGB に値が入っていても、透明度が掛け合わされて RGB が 0 として扱われてしまいます。

そのため、RGB と A(アルファ)を「完全に独立した値」として同時に保持することができません。

  • ストレート(Straight)
    RGB と A を別々の情報として保持する方式。
  • プリマルチプライド(Premultiplied)
    RGB には、あらかじめ RGB × Alpha の結果が格納される方式。

Blenderでのベイク処理も、この Premultiplied 前提の扱いが影響しているため、RGB と無関係なデータをアルファにそのまま焼くことができませんでした。

アルファの扱いについて詳しくは、以下の記事で解説しています。

スポンサーリンク

まとめ

Blenderのコンポジット機能を使えば、複数のテクスチャマップを 1 枚の RGBA テクスチャにまとめ、それぞれをアルファチャンネルなどに割り当てることができます。(R,G,Bのそれぞれにも割り当てることができます)

この方法は、Unity などのゲームエンジンで使うテクスチャの容量をできるだけ削減したい場合に有効です。

Photoshop などのペイントソフトがなくても、Blender だけでチャンネルパッキングが行えるので、ぜひ試してみてください。

コメント