Table of Contents

チュートリアル: レーザーと稲光

中級 アーティスト プログラマー

このチュートリアルでは、パーティクルやカスタムマテリアルを使ってレーザーや稲光を生成する方法を説明します。

このような稲光のアーチを作ることを想像してみてください。

media/particles-tutorials-lasers-1.gif

このエフェクトは、次のような特性を持った 1 本のひもです。

  • 固定された 2 点間を結ぶ

  • 素早く位置が変わる

  • 1 本のひもとして描画できる

稲光は一本の線状の帯なので、リボン シェイプビルダーを使ってレンダリングすることもできますが、いくつか大きな違いがあります。パーティクルです。

  • パーティクルは、順番ではなく、同時に生成されます。

  • パーティクルは一本の線または円弧のうえに現れますが、若干ランダムな位置を持つことで、稲光のような視覚を与えます。

  • パーティクルは、とても迅速に再出現します。

同時生成(Simultaneous spawning)

フレームごとにループするスポナーを作ります。このスポナーは、フレームごとに一定数(50 個とします)のパーティクルを産み出すものとします。

一度に表示されるのは 1 つのセットだけなので、エミッターの最大パーティクル数を 50 に制限し、同じライフスパンを与えます(例えば、0.2 秒)。

つまり、スポナーは毎フレーム 50 個のパーティクルを放出しようとしますが、パーティクルの数を制限しているため、最初のフレームでは 50 個のパーティクルが生成されます。

これらのパーティクルはすべて同じライフスパンを持っているので、50 個のパーティクルはすべて同時に消滅し、新たに 50 個のパーティクルが生成されることになります。

2 点を結ぶ

ここでは、Position (Arc) タイプのイニシャライザーを使用します。このイニシャライザーは、他のエンティティ(ターゲットエンティティ)の位置を円弧のもう一方の端として選び、自身のエミッターとターゲットエンティティとの間に引かれた円弧の上にパーティクルが出現させます。

Ordered チェックボックスをオンにすると、パーティクルをエミッターからターゲットエンティティに向かって等間隔で配置することができます。 これは、リボン シェイプビルダーを使ってレンダリングするときには重要です。なぜなら、パーティクルが円弧に沿ってランダムな(順序付けされていない)位置に表示されると、描画の順番や前後関係が混乱してしまうからです。 よって、Spawn Order タイプのイニシャライザーを追加して、パーティクルを順番に並べ替えなければなりません(これは稲光だけでなく、すべてのリボンに当てはまります)。

Position (Arc) イニシャライザーの初期設定ではランダムなオフセットを設定することも可能で、その際にはオフセットとしていくつかの小さな数値を設定します。

素早く位置を変える

パーティクルのライフスパンを、小さな数値(例:0.2 秒)に設定します。Time scale パラメータを使うと、さらにパーティクルシステム全体の速度をコントロールすることができます。

ここでは、何が起こっているのかをより分かりやすくするために、リボンの代わりにビルボード シェイプビルダーを使って、同じエフェクトを 30 倍にスローダウンしてみます。

media/particles-tutorials-lasers-2.gif

稲光を移動する

稲光のアーチを静止させるのではなく、ポイント A からポイント B へと移動させる方法があります。

media/particles-tutorials-lasers-3.gif

そのためには、いくつかの調整が必要です。

  • 生成レートを下げます。上の例では 600 / 秒として 0.1 の時間スケールで再生していますが、これは 1 フレームあたり約 1 個のパーティクルを生成することを意味しています。

  • アークポジショナーに、固定カウント(50)を設定します。フレームごとに生成されたパーティクルの総数に基づいて距離を補間するため、あまりに大量に連続してパーティクルを生成すると、すべてのパーティクルが円弧の始まりに留まってしまいます。そこで、カウントを 50 に設定することで、アークポジショナーにパーティクルの総数が 50 であることを通知することができます。

  • 稲光が歳出減する前に古い稲光が完全に消えるように、スポナーに遅延(delay)を設定します。そうしないと、リボンは古いパーティクルと新しいパーティクルをどのように分割してよいかわからなくなり、誤って接続してしまいます。

パーティクルを使ったレーザー

パーティクルでレーザーを作ることは、稲光を作ることとよく似ています。レーザーはまっすぐかつ逸れることがないので、パーティクルの数は少なくて済みます。 アークポジショナーの矢高(arc hight)を 0 にして、さらにランダムオフセットを (0, 0, 0) に設定することで、パーティクルを一直線に配置することができます。必要に応じてパーティクルの大きさを少しずつ変え、レーザービームが揺らいでいるように見せることもできます。

レーザーの注意点としては、通常は、ターゲットが動くとそれに合わせてレーザーも動くということです。アークポジショナーはアップデーターではなくイニシャライザーなので、すでに生成済みのパーティクルには影響を与えられず、後ろに残ってしまいます。これに対処するには 3 つの方法があります。

  • パーティクルを非常に高速に生成します。パーティクルのライフスパンが 1 〜 2 フレームであれば、レーザーの再出現が早すぎて、ユーザーが視覚的な違いに気づかなくなります。

  • ローカル空間にパーティクルを生成します。つまり、パーティクルはエミッターと一緒に動きます。ただし、エミッターを回転させたり、スケールしたりして、常にターゲットエンティティの方を向くようにしなければなりません。

  • カスタムアップデーターを作成します。アークポジショナーと似たような(あるいはもっと単純な)カスタムポストアップデーターを作成すれば、パーティクルの位置を毎フレーム更新させ、パーティクルが動いても 2 点間に正しく配置することができます。

これらの選択肢は、作りたいゲームのタイプによって、それぞれメリットとデメリットがあります。毎フレームごとにパーティクルを生成する方法は最も簡単でシンプルな方法であり、ほとんどのニーズに応えることができます。

カスタムマテリアルを使ったレーザー

カスタムマテリアルを使ってレーザーを作る方法は、ローカル空間でパーティクルを扱う方法と似ています。エミッターを手動で回転させたりスケールを変えたりして、常にターゲットエンティティと向かい合わせる必要があります。

ターゲットに向けた 1 つの軸を長さと呼び、残り 2 つの軸をレーザーの幅と呼ぶことにします。

回転したエンティティの下に配置された高さ 1 の円柱をレンダリングし、その円柱が伸びてターゲットポイントに到達することになります。

カスタムマテリアルは、スクロールするテクスチャーを円柱に貼り付けるために必要です。また、スクロールのない通常の発光マップを使用することもできます。その場合には、カスタムマテリアルは必要ありません。

パーティクルサンプルには、この方法でレーザーを作成する例がすでにあります。LaserOrientationScript では、ターゲットポイントに向かってエンティティを回転・スケーリングし、ComputeColorTextureScroll シェーダーではスクロールするテクスチャーをサンプリングしています。

サンプルプロジェクト

このページで紹介されているテクニックをプロジェクトに実装する場合は、新しい Sample: Particles プロジェクトを新規に作成して、Lasers シーンを開いてください。

Particles sample project

関連項目