DynamicVignetting.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System.Linq;
  2. using Controller.Bicycle;
  3. using SicknessReduction.Visual.Rendering;
  4. using UnityEngine;
  5. using UnityEngine.Rendering.Universal;
  6. namespace SicknessReduction.Visual.Vignetting
  7. {
  8. public enum VignettingSource
  9. {
  10. AngularVelocity,
  11. SteerAngle
  12. }
  13. public class DynamicVignetting : MonoBehaviour
  14. {
  15. //TODO: cite https://www.researchgate.net/publication/326760789_Assessing_vignetting_as_a_means_to_reduce_VR_sickness_during_amplified_head_rotations
  16. //TODO: there is a patent for this https://patents.google.com/patent/US9645395B2/en
  17. //TODO: check Fernandes & Feiner
  18. [Header("Unity Objects")] public ForwardRendererData forwardRenderer;
  19. public RbBicycleController bikeController;
  20. public Transform hmd;
  21. [Header("Restriction Data")] public VignettingSource vignettingSource;
  22. [Range(0, 1)] public float minRestriction = 0.3f;
  23. [Range(0, 1)] public float maxRestriction = 0.7f;
  24. [Range(0, 1)] public float distInnerOuterRadius = .05f;
  25. public float maxRestrictionChangePerSecond = 0.8f;
  26. [Tooltip("Depending on Vignetting source -> deg or deg/s")]
  27. public float threshold = 20f;
  28. //TODO: figure out what angular velocity means in my context
  29. private MaterialBlitFeature blitFeature;
  30. private Material blitFeatureMaterial;
  31. private bool blitFeatureAvailable;
  32. private ValueBasedRestrictionSuggestor steerAngleSuggestor;
  33. private QueueBasedRestrictionSuggestorVector3 angularVelocitySuggestor;
  34. private float currentRestriction;
  35. private void Start()
  36. {
  37. blitFeature = (MaterialBlitFeature) forwardRenderer.rendererFeatures.FirstOrDefault(f =>
  38. f is MaterialBlitFeature && f.name.Equals("VignetteBlitFilter"));
  39. blitFeatureAvailable = blitFeature != null;
  40. if (!blitFeatureAvailable) return;
  41. // ReSharper disable once PossibleNullReferenceException
  42. blitFeatureMaterial = blitFeature.settings.MaterialToBlit;
  43. if (vignettingSource == VignettingSource.AngularVelocity)
  44. {
  45. angularVelocitySuggestor =
  46. new QueueBasedRestrictionSuggestorVector3(threshold, minRestriction, maxRestriction, 180f); //deg/s
  47. }
  48. else if (vignettingSource == VignettingSource.SteerAngle)
  49. {
  50. steerAngleSuggestor =
  51. new ValueBasedRestrictionSuggestor(threshold: threshold, minRestriction, maxRestriction,
  52. bikeController.maxSteeringAngle); //deg
  53. }
  54. }
  55. private void Update()
  56. {
  57. if (!blitFeatureAvailable) return;
  58. float desiredRestriction;
  59. if (vignettingSource == VignettingSource.AngularVelocity)
  60. {
  61. angularVelocitySuggestor.AddValue(bikeController.rigidBody.transform.localEulerAngles);
  62. desiredRestriction = angularVelocitySuggestor.Suggestion;
  63. }
  64. else
  65. {
  66. steerAngleSuggestor.Value = bikeController.CurrentSteerAngle;
  67. desiredRestriction = steerAngleSuggestor.Suggestion;
  68. }
  69. var desiredChange = desiredRestriction - currentRestriction;
  70. var maxChange = Time.deltaTime * maxRestrictionChangePerSecond;
  71. var change = Mathf.Sign(desiredChange) * Mathf.Min(Mathf.Abs(desiredChange), maxChange);
  72. var correctedRestriction = Mathf.Clamp(currentRestriction + change, 0, 1);
  73. Debug.Log("V: CurrentRestriction = " + currentRestriction);
  74. Debug.Log("V: DesiredChange = " + desiredChange);
  75. Debug.Log("V: MaxChange = " + maxChange);
  76. Debug.Log("V: DesiredRestriction = " + desiredRestriction);
  77. Debug.Log("V: CorrectedRestriction = " + correctedRestriction);
  78. if (correctedRestriction > 0f)
  79. {
  80. blitFeature.SetActive(true);
  81. UpdateMaterial(correctedRestriction);
  82. return;
  83. }
  84. blitFeature.SetActive(false);
  85. }
  86. private void UpdateMaterial(float restriction)
  87. {
  88. currentRestriction = restriction;
  89. var r = Mathf.Clamp(1 - restriction, 0, 1);
  90. blitFeatureMaterial.SetFloat("_OFOV", r);
  91. blitFeatureMaterial.SetFloat("_IFOV", Mathf.Clamp(r - distInnerOuterRadius, 0, 1));
  92. }
  93. private void OnDestroy()
  94. {
  95. if (!blitFeatureAvailable) return;
  96. blitFeature.SetActive(false);
  97. }
  98. }
  99. }