4 / 4 SDFの曲面で反射と衝突時の光を作る
平面からSDFへ衝突形状を変えた作例を調べます。親の反射と、GPU Eventで生成する光を個別に確かめます。
SDFを衝突形状に使う
SDFCollision.unityを開き、SDFCollision.vfxを確認してください。SDFはSigned Distance Fieldの略で、空間の各点に物体表面までの符号付き距離を記録したデータです。表面付近で0となり、内側と外側を符号で区別します。
今回は、ウサギの形状を記録した3Dテクスチャを用意しています。新しくベイクする操作は行いません。平面一枚では表せない耳や背中などの曲面に対して、粒子がどのように反射するかを観察してください。
FallingParticlesのUpdateには、Gravity、Collision Shape、二つのTrigger Eventが並んでいます。Collision Shapeを選んでください。
| 項目 | 基準値・設定 |
|---|---|
| Shape | Signed Distance Field |
| Behavior | Collision |
| Mode | Solid |
| Distance Field | StanfordBunnySDF |
| Collision Attributes | Write Punctual Contact Only |
| Bounce | 0.4 |
| Friction | 1 |
| Lifetime Loss | 0 |
雨ではBehaviorがKillでしたが、こちらはCollisionです。衝突時の面の向きに応じて速度を変え、親を反射させます。親を反射する処理に、子の粒子の生成は必要ありません。
Distance Fieldの位置・回転・大きさは、Field Transformで決まります。表示用のBunnyとSDFの位置が一致する必要があるため、今回の演習ではモデルの子TransformとField Transformを変更しません。
衝突時の光と軌跡を分ける
On CollideのCountは1です。GPU EventからCollisionFlashesのInitializeへつながり、Set Position (From Source)で通知した親の位置へ短い光を出しています。Bunnyの表面に沿う反射はCollision Shapeが行い、発光はこの子のシステムが行います。
衝突した親の位置と、厳密な接触点を表すcollisionEventPositionは別の値です。この作例の発光は親の位置を引き継ぎます。前の波紋では、接触点のデータを読んで配置していました。子がどの値を読むかを区別してください。
Over Timeは衝突とは別に、移動中の親から通知します。こちらはTrailsへつながり、Particle Stripsで軌跡を表示しています。細い線が衝突しない場所にも残るのは、この通知があるためです。Stripsの内部は、今回は変更しません。
反射を残して発光だけを止める
FallingParticlesのUpdateで、Trigger Event (On Collide)の有効チェックだけを外した結果を予想してください。Collision ShapeとOver Timeは有効のままです。
保存してPlayすると、親の反射と軌跡は続きますが、新しい衝突時の光は出なくなります。停止後はOn Collideのチェックを戻してください。
Write Punctual Contact Onlyは、瞬間的な接触を記録する設定です。表面に接したまま滑る粒子から、同じ接触の通知を繰り返し出しにくくします。雨は衝突後に親を消すためWrite Always、こちらは反射して残るためこの設定を使っています。
Bounceだけを変えて比べる
Bounceは反射の強さです。0.4を0にしたときと、0.8にしたときの軌道を予想しましょう。発生数、Gravity、Frictionは固定します。
まず0でPlayし、跳ね返りが弱くなった状態を観察します。停止して0.8へ変え、表面から離れる動きと軌跡を比べてください。衝突位置や回数も変わり得るので、発光が増減した場合は、Countの変更と混同しないようにします。
比較後はBounceを0.4へ戻し、On Collideが有効であることを確認してください。平らな水面ならPlane、複雑な曲面ならSDFを使う理由と、親の反射・子の発光を分ける利点を自分の言葉で説明しましょう。
- 表示用Meshと、衝突に使うSDFの役割を区別できる。
- 発光の通知を止めても、反射と軌跡が続くことを確認した。
- 衝突時の光と移動中の軌跡が、異なる通知から生成されると説明できる。
- Bounceを0.4、Frictionを1、On Collideを有効へ戻した。