Files
TheDeclineOfWarriors/Assets/Scripts/SpaceWarpShaderGlobals.cs
T
2026-04-12 16:40:54 +07:00

90 lines
3.5 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
namespace Rendering
{
[ExecuteAlways]
[DisallowMultipleComponent]
[RequireComponent(typeof(Camera))]
public sealed class SpaceWarpShaderGlobals : MonoBehaviour
{
private static readonly int SpaceWarpCameraPositionId = Shader.PropertyToID("_SpaceWarpCameraPosition");
private static readonly int SpaceWarpPreviousCameraPositionId = Shader.PropertyToID("_SpaceWarpPreviousCameraPosition");
private static readonly int SpaceWarpCameraForwardId = Shader.PropertyToID("_SpaceWarpCameraForward");
private static readonly int SpaceWarpFrameTimeId = Shader.PropertyToID("_SpaceWarpFrameTime");
private static readonly int SpaceWarpTimeId = Shader.PropertyToID("_SpaceWarpTime");
[SerializeField] private bool _useUnscaledTime = true;
private Camera _camera;
private Vector3 _previousPosition;
private bool _initialized;
private void OnEnable()
{
_camera = GetComponent<Camera>();
RenderPipelineManager.beginCameraRendering += HandleBeginCameraRendering;
PushGlobals(true);
}
private void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= HandleBeginCameraRendering;
Shader.SetGlobalVector(SpaceWarpCameraPositionId, Vector4.zero);
Shader.SetGlobalVector(SpaceWarpPreviousCameraPositionId, Vector4.zero);
Shader.SetGlobalVector(SpaceWarpCameraForwardId, Vector4.zero);
Shader.SetGlobalFloat(SpaceWarpFrameTimeId, 0f);
Shader.SetGlobalFloat(SpaceWarpTimeId, 0f);
_initialized = false;
}
private void HandleBeginCameraRendering(ScriptableRenderContext context, Camera camera)
{
if (camera != _camera)
{
return;
}
PushGlobals(false);
}
private void PushGlobals(bool resetPreviousPosition)
{
if (_camera == null)
{
_camera = GetComponent<Camera>();
if (_camera == null)
{
return;
}
}
Transform cameraTransform = _camera.transform;
Vector3 currentPosition = cameraTransform.position;
if (resetPreviousPosition || !_initialized)
{
_previousPosition = currentPosition;
}
float frameTime = Application.isPlaying
? (_useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime)
: Mathf.Max(Time.deltaTime, 1f / 60f);
float timeValue = Application.isPlaying
? (_useUnscaledTime ? Time.unscaledTime : Time.time)
: Time.realtimeSinceStartup;
Vector3 forward = cameraTransform.forward;
Shader.SetGlobalVector(SpaceWarpCameraPositionId, new Vector4(currentPosition.x, currentPosition.y, currentPosition.z, 1f));
Shader.SetGlobalVector(SpaceWarpPreviousCameraPositionId, new Vector4(_previousPosition.x, _previousPosition.y, _previousPosition.z, 1f));
Shader.SetGlobalVector(SpaceWarpCameraForwardId, new Vector4(forward.x, forward.y, forward.z, 1f));
Shader.SetGlobalFloat(SpaceWarpFrameTimeId, Mathf.Max(frameTime, 0.0001f));
Shader.SetGlobalFloat(SpaceWarpTimeId, timeValue);
_previousPosition = currentPosition;
_initialized = true;
}
}
}