メインコンテンツへスキップ
  1. 記事/

OverlayMaterialの脇道あれこれ

UnrealEngine UE5.1 Materials
目次
この記事はUnreal Engine (UE) Advent Calendar 2023 のシリーズ 3、3 日目の記事です

UE5.1 から使える透過 OverlayMaterial、便利ですよね
今日はその OverlayMaterial のちょっとひねくれた使い方について紹介します

OverlayMaterial とは?
#

Mesh に Material を重ねて描画できる仕組みです
SkeletalMesh、StaticMesh のどちらにも適用でき、1 パスで描画できます

以前は Mesh を複製してレンダリングする際、ProceduralMesh、PosableMesh などの別コンポーネントが必要で、かつ 2 倍のパスが必要でしたが、 コレが登場したことで、お手軽かつ軽量に追加のエフェクトを付けられるようになりました

基本的な使い方はヒストリアさんの記事をどうぞ

観測範囲では専ら背面法アウトラインのために採用されている気がします 僕も今のところその使い方が主ですね

OverlayMaterial でできること
#

OverlayMaterial で使用される Mesh は、対象の Mesh を 1 つに統合したものです
なので、元の Mesh に設定している情報はほぼ使えると思って良いです

  • VertexColor
  • VertexNormal
  • UV …

Texture も自由に使用できます かなり自由が効くので、色々チャレンジしてみると良いでしょう

利用例:SkeletalMesh に適用するエフェクト
#

SkeletalMesh に適用することで、いろんなエフェクトがつけられます

Overlay Material Effects

利用例:アウトライン
#

背面法を使ったアウトラインが簡単に実現できます

横道1:部分的に適用したい
#

OverlayMaterial は 1 パスで描画するため、元の Mesh に複数の MaterialSlot があった場合、1 つに統合されてしまいます なので、特定の Material 部分だけに適用したい…となると、少し工夫が必要です

Alt text

OverlayMaterial は元の Mesh の情報を取得できるので、VertexColor を IDMap 代わりにしてみましょう

Alt text

VertexColor で区別することで、指定した部分にだけ適用することが可能になります

Alt text

この方法は、OverlayMaterial で Mask を使うときにも役立ちます 下記は実用例をボカしたものですが、アウトラインの太さを調整する Mask を適用する際に、VertexColor で振り分けすることで、領域ごとの MaskTexture を使えるようにしています

Alt text

横道2:欲張った VertexNormal の使い方
#

OverlayMaterial で背面法アウトラインを作る際、気をつけておかなければいけないのが、 OverlayMaterial は元の Mesh の情報を引き継ぐ、というところです

アニメキャラの場合、顔の VertexNormal を書き換えて、影の落ち方を調整する手法がありますが、 通常の背面法とは違い、同じ Mesh を使うことになるため、VertexNormal の方向へ拡張すると、アウトラインが乱れる場合があります

画像はその例です 左側にある方は VertexNormal を調整していますが、そのせいでアウトラインがうまく入らなくなっています

Alt text

Alt text

VertexNormal が駄目な場合は元の Normal 情報を VertexColor に入れておけば良いのですが、前の横道1でやったように、VertexColor を IDMap として使いたい場合はそれもできません

ではどうするか…

となったときが腕の見せ所
UVMap に埋め込むことにします

UE5 では Mesh の UVMap は 4 枚まで使えます
UVMap 1つで 2 チャンネル分…Normal(WorldNormal)は 3 チャンネルなので、2 枚あれば足りますね

というわけで Material はこんな感じにします

Alt text

結果はこのとおり
手前側が UVMap に埋め込んだ Normal を使ったもの、奥側が転写した VertexNormal をそのまま使ったほうです
きちんとアウトラインが入っています

Alt text

VertexNormal を転写してない方(画像左)と比べても遜色ない状態です

Alt text

おまけとして、Blender で UV に埋め込んだ際のスクリプトを載せておきます
あくまで参考です…

import bpy

uv1_name = 'uv_normal1'
uv2_name = 'uv_normal2'

def pack_normals_to_uv(mesh):

    uv1 = mesh.data.uv_layers.get(uv1_name)

    if uv1 is None:
        uv1 = mesh.data.uv_layers.new(name=uv1_name)

    uv2 = mesh.data.uv_layers.get(uv2_name)
    if uv2 is None:
        uv2 = mesh.data.uv_layers.new(name=uv2_name)


    mesh_normals = mesh.data.vertex_normals

    for loop in mesh.data.loops:
        x, y, z = mesh_normals[loop.vertex_index].vector
        print(loop.index, x, y, z)
        uv1.data[loop.index].uv = ((x + 1) * 0.5, (y + 1) * 0.5)
        uv2.data[loop.index].uv = ((z + 1) * 0.5 , 0.0)



if __name__ == '__main__':
    selected_mesh = bpy.context.active_object
    print(selected_mesh)
    pack_normals_to_uv(selected_mesh)

UVMap に情報を埋め込む、という事例は結構あるので、困ったときのアイデアの一つとして覚えておくと良いかもですね

関連記事

設定ファイルからScalability設定を操作する
UnrealEngine UE5.1 Scalability
TypePromotionについての考察
UnrealEngine UE5.1 TypePromotion C++ Blueprint
Android(Meta Quest2)でUnrealInsightを使う
UnrealEngine UE5.1 Mobile Android VR