※長時間の閲覧にはお気を付けください
本記事には激しく点滅するGif画像が含まれております。
取り扱う内容の性質上、早送りでわかりやすくしておりますので、閲覧の際には十分にお気を付けください。
ScriptとSphere
用意するのは数行のコードとSphere
、PointLight(Realtime)
だけです。
Shaderで頑張ったライトよりは見た目が劣りますが、
一人称視点でそこそこ高い天井なら誤魔化しも効くかと思います。
デモ
わかりやすくするために電球のスケールを10倍にしてます。
※以下Gifあり
見ての通り、PointLight
をSphere
の下に置いただけです。
MaterialのMetallic
やSmoothness
、Reflestions
あたりのパラーメーターを調整して
照り返しを生み出して、実際は光源ではないSphere
に光の表現を追加しています。
コード
using UnityEngine;
public class PerlinNoiseLight : MonoBehaviour
{
[SerializeField]
float maxIntensity;
[SerializeField]
float blinkSpeed;
Light blinkLight;
void Start()
{
blinkLight = this.gameObject.GetComponent<Light>();
}
void Update()
{
blinkLight.intensity = Mathf.PerlinNoise(Time.time * blinkSpeed, 0) * maxIntensity;
}
}
PerlinNoise
ランダムに点滅させたかったのでPerlinNoise
を使っています。
全く意味が分かりませんでしたが、
単純にランダムな値を返すものではなく、
入力値(xとy)の変化に合わせて徐々に変化するような乱数という事です。
端的に言えば、変化がなだらなかな乱数と言った感じでしょうか。1
というのが特徴だそうです。
言われてみれば、ランダムな値として利用できているにも関わらず、
突然真っ暗になったり、真っ暗な状態からいきなりMax状態の明るさになったりしていませんね。
実験として、単純にランダムな値を入れるとどうなるか試してみます。
Update
を下記のように変更します。
void Update()
{
blinkLight.intensity = Random.Range(0, maxIntensity);
}
※以下Gifあり
なかなかクレイジーな状態になりました。
PerlinNoise = 変化がなだらなかな乱数という表現に合点がいきました。
「でも実際の電球って寿命が近いとこういう激しい点滅もするよな~?」と思ったので
組み合わせてみました。
using UnityEngine;
public class PerlinNoiseLight : MonoBehaviour
{
[SerializeField]
float maxIntensity;
[SerializeField]
float blinkSpeed;
Light blinkLight;
int flashAdjustValue = 7;
void Start()
{
blinkLight = this.gameObject.GetComponent<Light>();
}
void Update()
{
if (blinkLight.intensity > maxIntensity / flashAdjustValue)
{
blinkLight.intensity = Mathf.PerlinNoise(Time.time * blinkSpeed, 0) * maxIntensity;
}
else //消えかけると激しく点滅
{
blinkLight.intensity = Random.Range(0, maxIntensity / 2);
}
}
}
よく見かける、消えかけたと思ったら激しく点滅してまた消えかける みたいな状態を再現できたかと思います。
※以下Gifあり
あとは、ライトの傘や外枠を作ってあげればより自然な見た目になるかと思います。
もっときれいな点滅を再現するなら、
電球のオブジェクトはShaderで点滅させて、
スポットライトやポイントライトのIntensityも連動して点滅させる必要がありそうです。