夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

ShaderTimeUpdater オブジェクト

本日はMRDLのSurfacesを勉強していきます。

前回は[HandMenu]とシーンの遷移の仕組みを見ていきました。

今回はHandMenu内の[ShaderTimeUpdater]オブジェクトを見ていきます。

〇ShaderTimeUpdater

‘‘‘ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information.

using UnityEngine;

namespace Microsoft.MRDL { [ExecuteInEditMode] public class ShaderTimeUpdater : MonoBehaviour { private void Update() { unloopedTime += Time.deltaTime;

        if (unloopedTime >= repeatInterval)
        {
            loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);
            float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime);
            if (blendAmount >= 1)
            {
                unloopedTime = 0;
            }
            noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);
        }
        else
        {
            noiseTime = unloopedTime;
        }

        noiseTime = Mathf.Repeat(noiseTime, repeatInterval);

        Shader.SetGlobalFloat("_NoiseTime", noiseTime);
    }

    [SerializeField]
    private float repeatInterval = 600f;
    [SerializeField]
    private float repeatBlendTime = 20f;
    [SerializeField]
    private AnimationCurve repeatBlendCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);

    private float unloopedTime;
    private float loopedTime;
    private float noiseTime;
}

} ‘‘‘

[ShaderTimeUpdater]コンポーネント[ExecuteInEditMode]の属性によってEditor上でUpdate関数が実行されます。

 unloopedTime += Time.deltaTime;

            if (unloopedTime >= repeatInterval)
            {
                loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);
                float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime);
                if (blendAmount >= 1)
                {
                    unloopedTime = 0;
                }
                noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);
            }
            else
            {
                noiseTime = unloopedTime;
            }

            noiseTime = Mathf.Repeat(noiseTime, repeatInterval);

            Shader.SetGlobalFloat("_NoiseTime", noiseTime);

Update関数内ではUnityEditor上の時間経過を取得しており、If分によりデフォルト値で600の[repeatInterval]が経過した場合とそうではない場合で処理が分けられています。

そうではない場合は[noiseTime]がそのまま経過時間になります。

  loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);
                float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime);
                if (blendAmount >= 1)
                {
                    unloopedTime = 0;
                }
                noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);

時間が経過した場合、 loopedTime つまりif文の中は600秒経過後に処理が走ります。

  loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);

Mathf.Repeat(time t , float f);

はtがfになるとその間をループする関数です。

[blendAmount]はアタッチされている[animationCurve]の[repeatBlendCurve]に設定されているunloopedTime(経過時間) - repeatInterval(リピート時間(600))=つまりループ後の経過時間の横軸から縦軸が返されます。

 if (blendAmount >= 1)
                {
                    unloopedTime = 0;
                }

この値が1より大きい場合 つまりデフォルト値の場合1200秒より大きい場合unloopedTimeは一度0に戻されます。

ここまでは時間経過によるループの処理でした。

  noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);

最後に[noiseTime]にunloopedtime、loopedTime,blendAmountによる値が入ります。

これはデフォルトの場合600から0に下がっていく値を示します。

            Shader.SetGlobalFloat("_NoiseTime", noiseTime);

最後に[Shader.SetGlobalFloat()]ですべてのShaderに対して[_NoiseTime]の変数にnoiseTimeを代入しています。

docs.unity3d.com

今後このShaderも中身を見ながらnoiseTimeのやっていることを見ていきます。