Files
JJBB/Assets/Project/Script/Shader/DirectionalLightSetter.cs
2024-08-23 15:49:34 +08:00

76 lines
2.6 KiB
C#

using Games.Events;
using Games.Scene;
using UnityEngine;
/// <summary>
/// 设置当前场景方向光到全局参数上
/// </summary>
// 注:因为美术效果很多时候阴影方向和镜面反射所需光线方向冲突,因此修改组件为可自由旋转
// 注:现在这个工具也用于处理平行光动态阴影开关
public class DirectionalLightSetter : MonoBehaviour
{
private const string _dirPropertyName = "_DirectionalLight";
// 镜面反射单独使用一个方向
private const string _specularPropertyName = "_SpecularLight";
private const string _colorPropertyName = "_DirectionalLightColor";
private const string _attenPropertyName = "_DirectionalLightAtten";
// 欧拉角度表示的镜面反射方向
public Quaternion specularRotation = Quaternion.identity;
private Light _lightComponent;
private void Start()
{
_lightComponent = GetComponent<Light>();
PlayerPreferenceData.SystemQualityDymShadow.onSettingUpdate += OnDynamicShadowToggle;
OnDynamicShadowToggle(PlayerPreferenceData.SystemQualityDymShadow);
EventDispatcher.Instance.Add(Games.Events.EventId.PostMainCameraMove, OnCameraMove);
SetLight();
}
private void OnDestroy()
{
if (!GameManager.applicationQuit)
{
PlayerPreferenceData.SystemQualityDymShadow.onSettingUpdate -= OnDynamicShadowToggle;
EventDispatcher.Instance.Remove(Games.Events.EventId.PostMainCameraMove, OnCameraMove);
}
}
private void OnDynamicShadowToggle(bool isOn)
{
_lightComponent.enabled = isOn;
}
public void SetLight(Light light)
{
Shader.SetGlobalVector(_dirPropertyName, transform.rotation * Vector3.back);
Shader.SetGlobalColor(_colorPropertyName, light.color);
Shader.SetGlobalFloat(_attenPropertyName, light.intensity);
Shader.SetGlobalVector(_specularPropertyName, specularRotation * Vector3.back);
}
public void SetLight()
{
SetLight(_lightComponent);
}
private float? _baseYaw;
private float _lastYaw;
private void OnCameraMove(object args)
{
if (_baseYaw == null)
{
_lastYaw = SceneLogic.CameraController.Yaw;
_baseYaw = _lastYaw;
}
else if (_lastYaw != SceneLogic.CameraController.Yaw)
{
var yaw = SceneLogic.CameraController.Yaw;
var deltaYaw = yaw - _baseYaw.Value;
_lastYaw = yaw;
var rotation = Quaternion.Euler(0f, deltaYaw, 0f) * specularRotation;
Shader.SetGlobalVector(_specularPropertyName, rotation * Vector3.back);
}
}
}