UDN
Search public documentation:

DevelopmentKitGemsRealTimeDeformationJP
English Translation
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 ホーム > Unreal Development Kit Gems > リアルタイムの変形
UE3 ホーム > マテリアルとテクスチャ > リアルタイムの変形

リアルタイムの変形


2011年7月に UDK に即して最終テスト実施済み

概要


DirectX 11 を UDK に導入することによって、リアルタイムのテセレーションとディスプレースメント (変位) が追加されるため、「Unreal」のレンダリングされたシーンにおけるビジュアルクオリティは、飛躍的に向上します。DirectX 11 のディスプレースメントは、テクスチャサンプラーを使用できるため、 World Position Offset よりも強力です。これだけでも頂点ディスプレースメントが一層魅力的なものになります。このドキュメントでは、ゲームプレイのインタラクションに基づいて変形するサーフェスの作成方法について解説します。

次のスクリーンショットで表示されている変形は、すべて、Link Gun という武器を使用してリアルタイムに実行されたものです。また、マテリアルは、2 種類あります。メタルの壁が、Link Gun の発射物によって衝撃を受けた部分でブレンドしています。フロアは、石のディフューズを使用しています。変形されると、スライム状のレイヤーをパンします。これによって、波の形状のシミュレートをともなって、サーフェスがディスプレースメントされます。

DX11RealTimeDeformation.jpg

注意 : DirectX 11 は、頂点ディスプレースメントを使用する場合に必要となりますが、デカールを使用せずにテクスチャでメッシュのサーフェスをペイントする場合には、必要ありません。DirectX 11 対応カードがない場合は、DirectX 11 が無効になるため、シェーダーが自動的に DirectX 11 を切ります。

技術上のセットアップ


本ドキュメントは、リアルタイムの変形を作成するのに協同して機能する 2 つの技術から構成されています。 hit mask は、サーフェスに適用される変形すべてを保存します。このコンポーネントによって、サーフェス近くのワールド座標が UV 空間座標に自動的に変形され、さらに、レンダリングターゲットに円が描かれます。hit mask をマテリアル内で使用すると、通常の状態とダメージを受けた状態からなる 2 つの処理を補間することができます。最後に、UnrealScript によってまとめられることによって、スクリプトベースのインタラクションとともに使用することができるようになります。

SceneCapture2DHitMaskComponent

通常、hit mask コンポーネントを使用する場合、 ドキュメント で定義されているようなテクスチャ座標を用います。 都合の悪いことに、このセットアップされたテクスチャ座標は、DirectX 11 の WorldDisplacement ノードでは使用できません。ただし、実験して確かめたところ、単一の平面が UV 座標のセット (両軸とも [0.f - 1.f] ) 全体を参照する場合は、ルックアップ座標をシフトして [0.5f - 1.f] x [ 0.f - 1.f] を用いれば、この hit mask レンダリングターゲットを使用することが可能となります。ただし、これによって、このドキュメントの活用が、フラットなサーフェスに限定されることになります。

マテリアル

マテリアルシステムによって hit mask コンポーネントのレンダリングターゲットがマスクとして使用されることによって、変形される部分と変形されない部分を表現する異なるシェーダーブランチ間の線形補間が実行されます。

下図は、hit mask コンポーネントのレンダリングターゲットを単にサンプリングするノードです。hit mask コンポーネントを使用する場合に通常必要となる Unmirror U を使わなければならないという効果が、改変されたテクスチャ座標によってオフセットされます。赤のチャンネルだけが補間目的で使用されます。赤以外のチャンネルが有用な情報を一切もたらさないためです。

DX11DeformMaterialLayout_HitMask.jpg

次は、hit mask コンポーネントのレンダリングターゲットにノイズを追加するノードです。hit mask コンポーネントは、白い円を配置するにすぎないため、それだけではかなりつまらないものです。これらの白い円と掛け合わされるノイズを追加することによって、より面白味のある変形が最終的に適用されることになります。

DX11DeformMaterialLayout_NoiseMask.jpg

次は、当のマテリアルに適用すべきマテリアルによって使用されるディスプレースメントのベクターです。UnrealScript によって変更されるため、これらのベクターは、デフォルトでは 0.f, 0.f, 0.f, 1.f にセットされています。このとき、回転方向のディスプレースメントベクターを使用することが重要です。さもなければ、ディスプレースメントの方向が不正になります。これらのベクターは UnrealScript でセットされます。

DX11DeformMaterialLayout_DisplacementVectors.jpg

ここから以降は、マテリアルの残りの部分について、特にコメントすべきものがありません。ディフューズおよびスペキュラ、スペキュラパワー、法線などのすべてが、補間のために、ノイズが入った hit mask コンポーネントのレンダリングターゲットを使用するため、変形の結果が一層分かりやすくなります。

DX11DeformMaterialLayout_Thumbnail.jpg

Unrealscript

ここで UnrealScript を使用して、上記技術を統合します。アクタが最初にワールド内に作成される場合、 PostBeginPlay() が実行されます。PostBeginPlay() は、C++ にあるコンストラクタの考え方に相当します。PostBeginPlay() では、まず、使用される hit mask コンポーネントのためにレンダリングターゲットが作成されます。オプションで、ダメージをフェードアウトさせることが可能です。それには、 SetFadingStartTimeSinceHit に正の値をセットします。こうすることによって、時間の経過とともに「表面」が通常の状態に復帰します。生物的壁のサーフェスなどに役立ちます。その後は、骨格メッシュのために、 CreateAndSetMaterialInstanceConstant によってマテリアルインスタンスコンスタントが作成されます。さらに、作成されたマテリアルインスタンスコンスタントは、その hit mask パラメータが、先に作成されているレンダリングターゲットにセットされます。最後に、アクタの回転に基づいて、ディスプレースメントベクターがセットされます。

アクタが破棄される場合は、 Destroyed が実行されます。ガーベジコレクションを容易にするために、あらゆるオブジェクト参照が none (なし) にセットされます。

アクタがダメージを受ける場合は、 TakeDamage が実行されます。この関数では、hit mask コンポーネントが更新されます。その結果、アクタが Link Gun (あるいは他のガン) に撃たれたときに、リアルタイムの変形が生じます。このエフェクトはシンプルなものですが、他の種類の武器をシミュレートするように拡張することができます。そのエフェクトはより小さくても大きくてもかまいません。基本的に無制限です。

デフォルトのプロパティによって、必要とされるすべてのオブジェクトが作成されるとともに、アクタが障害物となりコリジョン可能となります。

DX11DeformableMesh.uc
class DX11DeformableMesh extends Actor
  placeable;

var() const LightEnvironmentComponent LightEnvironmentComponent;
var() const SkeletalMeshComponent SkeletalMeshComponent;
var() const SceneCapture2DHitMaskComponent SceneCapture2DHitMaskComponent;
var() const IntPoint HitMaskSize;
var() const Name HitMaskMaterialParameterName;
var() const Name MinimumDisplacementParameterName;
var() const Name MaximumDisplacementParameterName;
var() const float MinimumDisplacement;
var() const float MaximumDisplacement;

var TextureRenderTarget2D HitMaskRenderTarget;

simulated function PostBeginPlay()
{
  local MaterialInstanceConstant MaterialInstanceConstant;
  local LinearColor LC;
  local Vector V;

  Super.PostBeginPlay();

  HitMaskRenderTarget = class'TextureRenderTarget2D'.static.Create(HitMaskSize.X, HitMaskSize.Y, PF_G8, MakeLinearColor(0, 0, 0, 1));
  if (HitMaskRenderTarget != None)
  {
    SceneCapture2DHitMaskComponent.SetCaptureTargetTexture(HitMaskRenderTarget);
    SceneCapture2DHitMaskComponent.SetFadingStartTimeSinceHit(-1.f);

    if (SkeletalMeshComponent != None)
    {
      MaterialInstanceConstant = SkeletalMeshComponent.CreateAndSetMaterialInstanceConstant(0);
      if (MaterialInstanceConstant != None)
      {
        MaterialInstanceConstant.SetTextureParameterValue(HitMaskMaterialParameterName, HitMaskRenderTarget);

        V = Vector(Rotation);
        V *= MinimumDisplacement;
        LC.R = V.X;
        LC.G = V.Y;
        LC.B = V.Z;
        MaterialInstanceConstant.SetVectorParameterValue(MinimumDisplacementParameterName, LC);

        V = Vector(Rotation);
        V *= MaximumDisplacement;
        LC.R = V.X;
        LC.G = V.Y;
        LC.B = V.Z;
        MaterialInstanceConstant.SetVectorParameterValue(MaximumDisplacementParameterName, LC);
      }
    }
  }
}

simulated function Destroyed()
{
  Super.Destroyed();

  SceneCapture2DHitMaskComponent.SetCaptureTargetTexture(None);
  HitMaskRenderTarget = None;
}

simulated function TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
  Super.TakeDamage(DamageAmount, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);

  SceneCapture2DHitMaskComponent.SetCaptureParameters(HitLocation, 16.f, HitLocation, false);
}

defaultproperties
{
  Begin Object Class=ArrowComponent Name=Arrow
    ArrowColor=(R=150,G=200,B=255)
    bTreatAsASprite=True
  End Object
  Components.Add(Arrow)

  Begin Object Class=DynamicLightEnvironmentComponent Name=MyDynamicLightEnvironmentComponent
  End Object
  LightEnvironmentComponent=MyDynamicLightEnvironmentComponent
  Components.Add(MyDynamicLightEnvironmentComponent)

  Begin Object Class=SkeletalMeshComponent Name=MySkeletalMeshComponent
    LightEnvironment=MyDynamicLightEnvironmentComponent
        bHasPhysicsAssetInstance=true
    CollideActors=true
    BlockActors=true
    BlockZeroExtent=true
    BlockNonZeroExtent=true
    BlockRigidBody=true
  End Object
  SkeletalMeshComponent=MySkeletalMeshComponent
  CollisionComponent=MySkeletalMeshComponent
  Components.Add(MySkeletalMeshComponent);  

  Begin Object Class=SceneCapture2DHitMaskComponent Name=MySceneCapture2DHitMaskComponent
  End Object
  SceneCapture2DHitMaskComponent=MySceneCapture2DHitMaskComponent
  Components.Add(MySceneCapture2DHitMaskComponent)

  CollisionType=COLLIDE_BlockAll
  BlockRigidBody=true
  bCollideActors=true
  bBlockActors=true
  HitMaskSize=(X=512,Y=512)
  HitMaskMaterialParameterName="HeightMask"
}

DX11DeformableMesh をゲームで使用する方法


DX11DeformableMesh (DirectX 11 の変形可能メッシュ) は、「Unreal Engine 3」の他のアクタと同じくらい簡単に使用することができます。コンテンツブラウザ内で、[Actor Classes] (アクタクラス) タブを見つけます。

DX11Deform_ActorClasses.jpg

タブがコンテンツブラウザ内で選択されたら、ゲームビューポート内で右クリックして、DX11DeformableMesh をワールド内に追加することができます。

DX11Deform_PlaceActor.jpg

そこから、プロパティをセットします。骨格メッシュや物理アセット、マテリアルなどといった骨格メッシュコンポーネントのプロパティをセットしなければなりません。

DX11Deform_DX11DeformSkelProp.jpg

DX11Deform_DX11DeformMatProp.jpg

次に、変形 (deformation) のプロパティをいくつか調整しなければならない場合があります。マテリアルパラメータ名が、使用しているマテリアルに必ず一致するようにします。

DX11Deform_DX11DeformProp.jpg

最後に、アクタの向かっている方向が、変形されるサーフェスがある場所を指すようにする必要があります。正しい方向に向かわせるには、矢印が役立ちます。使用される平面メッシュもこのために役立ちます。ただし、厳密には、このテクニックが機能するのに平面が必要となるということはありません。たとえば、一部の部分だけが変形可能なメッシュを作ることができます。

DX11Deform_Orientation.jpg

結論


複数の技術を組み合わせて使うことによって、新たな魅力ある技術を作り出し、それによってゲームの質を向上させて、ひときわ優れたものにすることができます。

ダウンロード


  • このドキュメントで使用されているコンテンツは、 ここから ダウンロードすることができます。

関連テーマ