[Unity] 透過のあるテクスチャ表現/Metallic+Smoothnessを1枚のテクスチャで表現

  • UVを編集してマッピングの反復を1 x 1にする
  • Unityで、MetallicとSmoothnessを1枚のテクスチャとして割り当て
  • Unityで、透過のあるテクスチャを指定

この説明では、Unity 2017.1.1f1を使用しました。

葉などの透過があるテクスチャをUnityに渡します。
モデリング形状の例として「植物を作る」で作成した鉢植えを使用します。

マスターサーフェスとして、鉢、土、葉、幹、枝、に分かれています。
Unityに持っていきますので、いくつかを1テクスチャに収めてしまうようにします。
テクスチャは、512×512ピクセルの「拡散反射」「法線マップ」「メタリック(RGB)+スムーズネス(A)」、に置き換えます。

ポリゴンメッシュに変換

マスターサーフェスごとに、ポリゴンメッシュとして変換してまとめました。

鉢(flowerpot)、土(soil)、幹(trunk)、枝(branches)、葉(leaves)、に分けています。
このうち、幹と枝は同じテクスチャを使用しているため1つにまとめます。

マッピングの90度回転と反復をなくす

左が幹の材質のマッピング、右が枝のマッピングです。
「反復」だけ指定が異なります。

Unityではマテリアルの反復指定には対応していますが、反復数が異なる場合は別々のテクスチャに分ける必要があります。
ここを統一化するため、マッピングの反復自身をなくしてしまいます。

反復が4 x 20の幹は、ズームしていくと以下のようにマッピングされています。

また、テクスチャは「90度回転」させています。
UV図面では以下のようになっています。

マスターサーフェス「幹」のマッピングで「90度回転」をオフに、「反復」を1×1にし、UVを(0,0)を中心としてU方向に4倍、V方向に20倍します。
以下の手順で操作を行います。

  1. ブラウザで「trunk」形状を選択
  2. 表面材質ウィンドウのマッピングで「90度回転」をオフにする
  3. 表面材質ウィンドウのマッピングで「反復」を1 x 1にする
  4. 形状編集モード + 面選択モードにする
  5. すべての面を選択
  6. 「グリッドスナップ」をオンにする
  7. UV図面のマニピュレータの回転操作で、すべてのUV面を90度回転させる
  8. ツールボックスの「作成」-「移動/複製」-「移動」-「数値入力」を選択
  9. UV図面の(0, 0)をクリック
  10. 「トランスフォーメーション」ウィンドウの拡大縮小で、4, 20 を指定して「OK」ボタンを押す


以下のようになりました。

表面材質のパラメータは90度回転や反復をしようしないようにし、UVで調整しました。
表面材質ウィンドウのマッピングでは、拡散反射/法線/バンプのいずれも「90度回転」をオフ、「反復」を1×1としました。

同様に、「branches」名の枝についても、表面材質ウィンドウのマッピングの「90度回転」をオフ、「反復」を1×1とし、UVを調整します。

これで「trunk」「branches」のどちらも同じ表面材質指定になりましたので、
1つのポリゴンメッシュ、マスターサーフェスにまとめます。

幹と枝を1つにまとめる

ブラウザで「trunk」「branches」を選択し、ツールボックスの「編集」-「メッシュ」-「結合/除去」-「オブジェクトの結合」を選択します。
これで、2つのポリゴンメッシュは1つになりました。
ブラウザで形状名を「trunk_branches」に変更、形状情報ウィンドウの限界角度を調整、
「ファイスグループ情報」の2つのグループ指定を選択し、右下の削除ボタンを押します。

これで、幹と枝には「幹」のマスターサーフェスが1つ割り当てられた状態になりました。
「枝」のマスターサーフェスは不要になりましたので、ブラウザで選択して削除します。

鉢と土を1つにまとめる

「flowerpot」名の「鉢」と「soil」名の「土」を、1つにまとめます。
また、テクスチャには「葉」のテクスチャも入れてしまいます。

鉢/土/葉のテクスチャを1つにまとめる

512 x 512ピクセルのテクスチャ画像を2 x 2 分割した状態で、ペイントツールでテクスチャを編集しました。
左が拡散反射のテクスチャ、右が法線マップのテクスチャです。

拡散反射のテクスチャは、透過としてアルファ要素を持つpng形式で出力しました。
葉の周囲のアルファは0を指定しています。
拡散反射のテクスチャは、plant_flowerpot_soil_leaf_diffuse.png という名前にしました。
法線のテクスチャは、plant_flowerpot_soil_leaf_normal.pngという名前にしました。
このテクスチャをShade3Dに読み込みます。

マスターサーフェスの作成

「plant_flowerpot_soil」というマスターサーフェスを作成し、
「イメージ/拡散反射」「イメージ/法線」のマッピングレイヤを指定しました。

「flowerpot」と「soil」形状をブラウザで選択し、「plant_flowerpot_soil_leaf」のマスターサーフェスを割り当てました。
この段階でテクスチャはずれることになるため、UVを調整します。

UVの調整

鉢(flowerpot)、土(soil)、葉(leaves)のUVを調整します。

ブラウザで「flowerpot」を選択し、UV図面を表示します。
UV図面上ですべての面を選択し、
ツールボックスの「作成」-「移動/複製」-「移動」-「数値入力」などを使用して
UV(0, 0)を中心として1/2倍にします。

ブラウザで「soil」を選択し、UV図面上ですべての面を選択し、
UV(0, 0)を中心として1/2倍にしてから、Uを+0.5の位置に移動します。

透視図では、以下のように鉢と土は元と同じ状態で表示されるようになりました。

これで「土」と「鉢」のマスターサーフェスは不要になりましたので削除します。

「葉」のマスターサーフェスを選択し、「イメージ/拡散反射」「イメージ/法線」のマッピング画像を「plant_flowerpot_soil_leaf_diffuse.png」「plant_flowerpot_soil_leaf_normal.png」に変更します。
「アルファ透明」が有効であることを確認します。

テクスチャはずれることになるため、すべての面を選択し、
UV図面でUVを0.5倍してからVを+0.5の位置に移動させます。

プレビューレンダリングすると、以下のようになりました。

これで、不要になったテクスチャを削除。
「葉」のマスターサーフェス名を「leaf」に、「幹」のマスターサーフェス名を「trunk_branches」に変更して以下のようになりました。

鉢と土のMetallic+Smoothness用のテクスチャを作成

「鉢」と「土」は同じマスターサーフェスを使用しています。
しかし、「鉢」と「土」は異なる光沢で荒さ(ラフネス)が異なります。
この部分をテクスチャで表現することにしました。
なお、Unityでは「Standard Shader」として、「Metallic」をRGB、「Smoothness」をAの1枚のテクスチャをまとめる必要があります。
「Smoothness」は「荒さ(ラフネス)」の逆になり、Smoothnessの値が大きいほど表面が滑らかになります。
512×512ピクセルの左上が「鉢」、右上が「土」のテクスチャとなっています。

「鉢」はMetallicを0.1、Smoothnessを0.4、
「土」はMetallicを0.0、Smoothnessを0.0、とすることにします。
グレイスケールで画像として表現します。
これは、以下のように2Dペイントツールで編集しました。

左がRGB、右がAとなり、plant_metallic_smoothness.png名のpngファイルとして、RGB+A情報を保存しました。
これはShade3Dでは読み込まなくても問題ありません。

以上で、4つのポリゴンメッシュ、3つのマスターサーフェス(マテリアル)、
2つの拡散反射テクスチャと2つの法線マップテクスチャ、
1つのMetallic+Smoothnessのテクスチャ、が用意できました。

Shade3DでFBXエクスポート

Shade3DからFBXエクスポートします。plant.fbxとして出力しました。
オプション指定は「テクスチャを持つマテリアルを渡す」のときの指定と同じです。

以降は、Unityでの作業となります。

UnityでFBXインポート

Unity上でテクスチャ画像とfbxをインポートして、不要なマテリアルを削除して以下のようになりました。

fbxインポートについては、「テクスチャを持つマテリアルを渡す」もご参照くださいませ。

マテリアルを調整

シーンにplantの形状を読み込むと以下のようになります。

まだ、「葉」の透過の調整と、鉢と土のMetallic + Smoothnessの調整ができていません。

鉢と土で、「Metallic + Smoothness」を調整

「plant_flowerpot_soil」のマテリアルを選択し、Inspectorウィンドウを開きます。
Metallicの右の小さい丸をクリックし、「plant_metallic_smoothness」画像を指定します。

これで、鉢と土にMetallicとSmoothnessのパラメータがテクスチャとして与えられました。
異なる「Metallic」「Smoothness」があっても1マテリアルで共有できます。
このような方法はよく使用されます。

葉の透過を調整

「leaf」のマテリアルを選択し、Inspectorウィンドウを開きます。
「Rendering Mode」が「Transparent」になっています。

この場合は、透過はされていますがうっすらと透明が残ってしまってます。

「Rendering Mode」を「Cutout」にすると、アルファ値によりトリミングされます。

ただし、Standard Shaderの場合は、葉の裏を向くと面が非表示になります。

そのため、「マテリアルとシェーダーについて/裏面も表示する」のようにStandardを継承した、裏面を表示するシェーダーを作成することにします。

葉のシェーダーを作る

裏面も表示する「Cull Off」の指定に加えて、Cutoutの指定が必要となります。
以下のようなシェーダーを記述しました。


Shader "Custom/standard_cullOff_cutout" {
  Properties {
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _Cutoff ("Cutoff" , Range(0, 1)) = 0.5     // <== 追加.
    _NormalMapIntensity ("Normal Intensity", Float) = 1  
    _NormalMap("Normal Map", 2D) = "bump" {}
    _Glossiness ("Smoothness", Range(0,1)) = 0.5
    _Metallic ("Metallic", Range(0,1)) = 0.0
  }
  SubShader {
    Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" } // <== 変更.
    LOD 200
    Cull Off
    
    CGPROGRAM
    // Physically based Standard lighting model, and enable shadows on all light types
    #pragma surface surf Standard fullforwardshadows alphatest:_Cutoff  // <== alphatest:_Cutoff 追加.

    // Use shader model 3.0 target, to get nicer looking lighting
    #pragma target 3.0

    sampler2D _MainTex;
    sampler2D _NormalMap;

    struct Input {
      float2 uv_MainTex;
    };

    half _Glossiness;
    half _Metallic;
    fixed4 _Color;
    half _NormalMapIntensity;

    void surf (Input IN, inout SurfaceOutputStandard o) {
      // Albedo comes from a texture tinted by color
      fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
      o.Albedo = c.rgb;
      // Metallic and smoothness come from slider variables
      o.Metallic = _Metallic;
      o.Smoothness = _Glossiness;
      o.Alpha = c.a;

      o.Normal = lerp( float3(0,0,1), UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)), _NormalMapIntensity);
    }
    ENDCG
  }
  FallBack "Transparent/Cutout/Diffuse"    //<== 変更.
}

「Properties」に「_Cutoff」を追加。
「SubShader」内のTagsで「”Queue”=”AlphaTest” “RenderType”=”TransparentCutout”」を指定します。
これにより、アルファ値を参照したピクセル透過が考慮されます。
「#pragma」で「alphatest:_Cutoff」を指定することで、アルファ値が_Cutoffで指定した値以下の場合は、ピクセル単位で表示しない指定になります。
「FallBack」で”Transparent/Cutout/Diffuse”とすることで、影の表示もテクスチャのアルファ値でくりぬきが行われます。
このシェーダーを「standard_cullOff_cutout.shader」として保存しました。

「leaf」のマテリアルにこのシェーダーを指定します。
結果として以下のようになりました。

これで、Shade3DからUnityに鉢植えを渡す作業は完了しました。
今回は、テクスチャのアルファを使用した透過表現、
MetallicとSmoothnessを1枚のテクスチャで表現、
という、リアルタイムではよく使用される手段についてでした。

これで、小物類はだいたい表現できるようになったかと思います。
次回は、建物を渡して光源を調整、という規模の少し大きな表現を行う予定です。

カテゴリー: Unityに形状を渡す