🔧

URPのShader変数_Timeの実装について

2021/07/25に公開

前書き

Built-in Render PipelineUniversal Render PipelineでShaderで使用できる_Timeの実装が違うらしいので調べてみました。

環境

Unity 2020.3.12f1
Universal RP 10.5.0
High Definition RP 10.5.0

Built-in Render Pipelineの_Time

ドキュメントを見てみると、ステージ(レベル)のロードからの時間(Time.timeSinceLevelLoad) と書かれています。
ここで言うステージはたぶんシーンのことを指すと思うので、シーンをロードすると毎回0から始まるようです。
https://docs.unity3d.com/ja/2020.3/Manual/SL-UnityShaderVariables.html

Universal Render Pipelineの_Time

URPで_Timeを設定している箇所はRuntime/ScriptableRender.csSetShaderTimeValues関数で行っており、呼び出し元はExecute関数です。
そこに設定するためのtime変数の定義があります。
https://github.com/Unity-Technologies/Graphics/blob/603b05681eeed66e625316f69ddbe3fbd26bf60f/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs#L629
定義は以下の通りです。

#if UNITY_EDITOR
    float time = Application.isPlaying ? Time.time : Time.realtimeSinceStartup;
#else
    float time = Time.time;
#endif
    float deltaTime = Time.deltaTime;
    float smoothDeltaTime = Time.smoothDeltaTime;
    ...
    SetShaderTimeValues(cmd, time, deltaTime, smoothDeltaTime);

コードを見ると、エディタ上ではプレイ中だとTime.time、非プレイ中だとTime.realtimeSinceStartupを入れています。
エディタ上でない場合はTime.timeを入れています。

確かに_Timeの実装が異なっているが確認できます。

おまけ:Time.realtimeSinceStartupって何?

名前の通りですが、アプリケーションを起動してからの時間です。
Time.timeScaleに影響しないのでゲーム中に一時停止に時間を計りたい、アニメーションさせたい場合は良さそうかもしれません。
ただ、プラットフォームやハードウェア依存なので気を付ける必要がありそうです。
https://docs.unity3d.com/ja/current/ScriptReference/Time-realtimeSinceStartup.html:embed:cite

High Definition Render Pipelineの_Time

HDRPはRuntime/RenderPipeline/Camera/HDCamera.csUpdate関数で定義されています。
https://github.com/Unity-Technologies/Graphics/blob/603b05681eeed66e625316f69ddbe3fbd26bf60f/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs#L728:embed:cite
定義は以下の通りです。

#if UNITY_EDITOR
    newTime = Application.isPlaying ? Time.time : Time.realtimeSinceStartup;
    deltaTime = Application.isPlaying ? Time.deltaTime : 0.033f;
#else
    newTime = Time.time;
    deltaTime = Time.deltaTime;
#endif
    time = newTime;
    lastTime = newTime - deltaTime;

time変数が_Timeに代入されている値です。
実装自体はURPと変わらないようです。

最後に

実装が異なっていましたが、あまり影響はなさそう雰囲気でした。

転載元

https://eorf.hatenablog.com/entry/2021/06/30/035117

Discussion