1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RuntimeMeshComponentについて

Posted at

RuntimeMeshComponentとは?

Unreal Engine4にて、動的にサーフェイスメッシュを扱うためには、ProceduralMeshComponent(PMC)があります。RuntimeMeshComponent(RMC)はその代替として開発された、より効率的で多様な機能があって多様なユースケースに対応できるのだそうです。どのくらい優れているかは、以下の指標が端的に示しています。

  1. 50-90% Lower memory usage than PMC (PMCよりメモリ効率が良い)
  2. 30-100% lower render thread cpu time (PMCよりレンダリング時間が短い)
  3. Static draw path for maximum rendering performance (静的なメッシュに対しては、最高のレンダリング性能)
  4. Dynamic Draw path for efficient frequent updates. (高頻度で変化する動的なメッシュに対して効果的)

このライブラリはいろんなところで使われているようなのですが、日本語での解説が少なかったり、提供されているC++のサンプルがそのまま動かなかったりという問題があります。ここでは、簡単なサンプルを試すまでの手順を説明したいと思います。なお、UE4のバージョンは4.25、Visual Studio 2019 Communityを使っています。

インストール

Gitのページでソースコードをダウンロードします。マーケットプレイスにはありません。

適当なプロジェクト(RMCTest)を作り、プロジェクトフォルダの最上位階層に、Pluginsフォルダを作ります。その中に、ソースコードを解凍してできたRuntimeMeshComponentフォルダを配置します。UE4の仕様では、Pluginsフォルダの中にあるxxxx.upluginという拡張子のファイルを再帰的に探して読み込むようです。うまくいくと、ウィンドウ -> デベロッパーツール -> モジュール
内に当該プラグインが発見できます。

image.png

簡易的なC++サンプル

ブループリントについては、サンプルプロジェクトを見れば分かるので、ここではC++について触れます。バージョンが違うためか、そのままでは動きません。

まずは、RuntimeMeshActorを継承した適当なクラスを作ります。インストールが成功していれば候補に出てくるはずです。ここではサンプルに倣って、ABasicPMCStyleRMCと名前を付けます。
image.png

続いて、C++のプロジェクトで、当該プラグインを読み込ませるための設定を行います。以下のように、PublicDependencyModuleNamesRuntimeMeshComponentを追記します。ここまでやって、リビルドしたところで、RMCTest.uprojectを右クリックしてGenerate Visual Studio Project Filesをしておいた方が良いようです。

RMCTest.Build.cs
using UnrealBuildTool;

public class RMCTest : ModuleRules
{
	public RMCTest(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "RuntimeMeshComponent" });

	}
}

続いて、作成したABasicPMCStyleRMCに簡易的なメッシュに色を付けたものを自動生成するコードを追加します。元のサンプルだと、OnConstructionを使っていたのですが、どうしても呼ばれなかったので、BeginPlay内に生成コードを入れています。結果としては同じになるかと思いますが、もしOnConstructionを使った方がいい場合は誰か教えてください。

ここに書いてあるように、マテリアル情報はきちんとUI上で付与する必要があります。

BasicPMCStyleRMC.h

# pragma once

# include "CoreMinimal.h"
# include "RuntimeMeshActor.h"
# include "BasicPMCStyleRMC.generated.h"

UCLASS()
class ABasicPMCStyleRMC : public ARuntimeMeshActor
{
	GENERATED_BODY()
	
public:	
	UPROPERTY(EditAnywhere)
	UMaterialInterface* Material;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;


public:	
	// Sets default values for this actor's properties
	ABasicPMCStyleRMC();
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

続いて、関数の実装部分です。
StaticProviderを作って、そこに頂点やインデックス、マテリアル情報などを設定していくのは、PMCと同じような考え方です。OBJファイルと同じだと思えば、そんなに混乱はないですね。Blueprintでも勿論かけますが、公式サイトではC++での実装を推奨しています。これは単純に速さのためだそうです。

BasicPMCStyleRMC.cpp
# include "BasicPMCStyleRMC.h"
# include "Providers/RuntimeMeshProviderStatic.h"

// Sets default values
ABasicPMCStyleRMC::ABasicPMCStyleRMC() : Material(nullptr)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}


// Called when the game starts or when spawned
void ABasicPMCStyleRMC::BeginPlay()
{
	Super::BeginPlay();
    UE_LOG(LogTemp, Log, TEXT("BeginPlay"));
    URuntimeMeshProviderStatic* StaticProvider = NewObject<URuntimeMeshProviderStatic>(this, TEXT("RuntimeMeshProvider-Static"));

    if (StaticProvider)
    {
        // The static provider should initialize before we use it
        GetRuntimeMeshComponent()->Initialize(StaticProvider);
        UE_LOG(LogTemp, Log, TEXT("TriMat"));


        // This creates 3 positions for a triangle
        TArray<FVector> Positions{ FVector(0, -50, 20), FVector(0, 0, 100), FVector(0, 50, 0) };

        // This creates 3 vertex colors
        TArray<FColor> Colors{ FColor::Blue, FColor::Red, FColor::Green };

        // This indexes our simple triangle
        TArray<int32> Triangles = { 0, 1, 2 };

        TArray<FVector> EmptyNormals;
        TArray<FVector2D> EmptyTexCoords;
        TArray<FRuntimeMeshTangent> EmptyTangents;
        StaticProvider->CreateSectionFromComponents(0, 0, 0, Positions, Triangles, EmptyNormals, EmptyTexCoords, Colors, EmptyTangents, ERuntimeMeshUpdateFrequency::Infrequent, true);
        StaticProvider->SetupMaterialSlot(0, TEXT("TriMat"), Material);

    }
}

// Called every frame
void ABasicPMCStyleRMC::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

続いて、マテリアル情報を作ります。M_Testという名前で作成しています。ここで重要なのは、ベースカラーとしてVertex Colorを充てることです。
image.png

次に、作成したABasicPMCStyleRMCをベースにしたブループリントを作ります。BP_BasicPMCStyleRMCとでもして、適当なフォルダに作っておきましょう。作成したブループリントのアクターをレベルに配置して、詳細パネルでMaterialをM_Testに設定します。これで下の画面のように表示されれば成功です。

image.png

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?