前回の第13回「パーティクルを炎のように表現する」では、アニメーションするパーティクルの動きやかたち、色を炎に近づけた。今回は、さらに炎が映り込む光を床に加える。その光にも、揺らぐようなアニメーションを与えたい。
炎の光を加える
3次元空間には、すでにDirectionalLightクラスで平行光源が与えてある(第1回の「DirectionalLightクラスで平行光源を定める」参照)。太陽光のように同じ向き(平行)に進み、距離によって強さが変わらない光だ。炎の床への映り込みは、PointLightクラスの「点光源」として加える。ひとつの点からすべての向きに光を放ち、光源から離れるほど明るさは弱まる。電球のような光だ(再掲第1回図3)。
アニメーションさせる炎を定めるクラス(FireObject)は、取りあえず前回と同じまま使う(再掲第12回コード1)。
光源を床に加えるには、床の平面のMesh.materialプロパティに定められたStaticLightPickerオブジェクトを得る。MaterialBase.lightPickerプロパティに与えられたオブジェクトだ。第13回コード3「アニメーションするパーティクルに柔らかな円形のテクスチャを与える」では、StaticLightPickerオブジェクトは、初期設定の関数(initialize())でつぎのように変数(lightPicker)に納めておいた。
点光源はPointLight()コンストラクタを呼び出してつくる。そのPointLightオブジェクトを、StaticLightPicker.lightsプロパティから得られる配列に加えればよい。そこで、炎のアニメーションを始める関数(startFire())は、以下のように書き替える。
LightBase.colorプロパティには、炎と同じ赤(0xFF3301)を定めた(第13回の「パーティクルのカラーをアニメーションさせる」参照)。また、光源や平面のDisplayObject.transformプロパティはインスタンスの変換情報をもち、Transform.positionプロパティで位置座標が3次元のVector3Dオブジェクトで得られる。点光源(light)と炎のオブジェクトの位置は、互いのこのプロパティで揃えた。
これで、炎のパーティクルのアニメーションする床の上が、炎と同じ赤い光で照らされる。ただし、最後の炎のアニメーションの下の床に光が灯らない(図1)。
炎が増えてもその数だけ床に光を照らすには、つぎのように床の平面をつくる関数(createPlane())の中で平面のMethodMaterial.modeプロパティをMethodMaterialMode.MULTI_PASSに定める。
これで、すべての炎の下の床に赤い光が灯った(図2)。ここまでの手を加えたのが、以下にまとめたコード1だ。ただし、光源はアニメーションさせていないので、床に映る灯りに動きはない。
光をアニメーションさせる
つぎに、光源にも揺らぐアニメーションを加えたい。操作するのは、光の届く距離や反射を定めるつぎの4つのプロパティだ。始めの2つは点光源のPointLightクラスに備わり、後の2つは親のLightBaseクラスのプロパティになる。これらの値をランダムに変えることで、光が揺らぐようなアニメーションにしたい。
- PointLight.fallOff:光が届く距離の最大値(デフォルト値10000)
- PointLight.radius:光が届く距離の最小値(デフォルト値9000)
- LightBase.diffuse:拡散反射(乱反射)の強さを示す0以上の数値(デフォルト値1)
- LightBase.specular:鏡面反射の強さを示す0以上の数値(デフォルト値1)
そこで、PointLightオブジェクトはつぎのように、炎のアニメーションを始める関数(startFire())で炎のオブジェクト(fireObject)のプロパティ(light)に加える。そして、炎のオブジェクトを定めるクラス(FireObject)は、以下のとおり新たに加えるメソッド(animateLight())で前述4つのプロパティが引数値により変えられるようにした。そのうえで、アニメーションの関数(render())が、すべての炎のオブジェクトを取り出し、メソッドにランダムな値を渡している。
これで、炎が照らす床の光にもアニメーションが加わった。光の届く範囲や反射の強さがランダムに替わるため、炎の灯りがバナーのように揺らぐ。jsdo.itに掲げたサンプル1でアニメーションは確かめられる[1]。スクリプトは以下に、コード2「光のアニメーションを加えた炎のクラス」およびコード3「床に照らした炎の光をアニメーションさせる」としてまとめた。
コードの行数もかなり増えた。今回はこのあたりで切上げよう。次回は、床の反射にさらにこだわって、お題を仕上げたい。