|
@@ -6,57 +6,105 @@ using UnityEngine.Rendering.Universal;
|
|
|
|
|
|
namespace SicknessReduction.Visual.Vignetting
|
|
namespace SicknessReduction.Visual.Vignetting
|
|
{
|
|
{
|
|
|
|
+ public enum VignettingSource
|
|
|
|
+ {
|
|
|
|
+ AngularVelocity,
|
|
|
|
+ SteerAngle
|
|
|
|
+ }
|
|
|
|
+
|
|
public class DynamicVignetting : MonoBehaviour
|
|
public class DynamicVignetting : MonoBehaviour
|
|
{
|
|
{
|
|
//TODO: cite https://www.researchgate.net/publication/326760789_Assessing_vignetting_as_a_means_to_reduce_VR_sickness_during_amplified_head_rotations
|
|
//TODO: cite https://www.researchgate.net/publication/326760789_Assessing_vignetting_as_a_means_to_reduce_VR_sickness_during_amplified_head_rotations
|
|
- //TODO: there is a patent for this (WTF) https://patents.google.com/patent/US9645395B2/en
|
|
|
|
|
|
+ //TODO: there is a patent for this https://patents.google.com/patent/US9645395B2/en
|
|
//TODO: check Fernandes & Feiner
|
|
//TODO: check Fernandes & Feiner
|
|
|
|
|
|
- private const float DIST_IFOV_OVOF = .2f;
|
|
|
|
|
|
+ private const float DIST_IFOV_OVOF = .10f;
|
|
|
|
|
|
[Header("Unity Objects")] public ForwardRendererData forwardRenderer;
|
|
[Header("Unity Objects")] public ForwardRendererData forwardRenderer;
|
|
public RbBicycleController bikeController;
|
|
public RbBicycleController bikeController;
|
|
public Transform hmd;
|
|
public Transform hmd;
|
|
|
|
|
|
- [Header("Restriction Data")] public float minRestriction = 0f; //from Fernandes & Feiner
|
|
|
|
- public float maxRestriction = 80f; //from Fernandes & Feiner
|
|
|
|
- public float angularVelocityThreshold = 20f; //deg/sec check in Fernandes & Feiner
|
|
|
|
- public float steerAngleThreshold = 15f; //deg/sec check in Fernandes & Feiner
|
|
|
|
- public float leanAngleThreshold = 20f; //deg/sec check in Fernandes & Feiner
|
|
|
|
|
|
+ [Header("Restriction Data")] public VignettingSource vignettingSource;
|
|
|
|
+ [Range(0, 1)] public float minRestriction = 0.3f;
|
|
|
|
+ [Range(0, 1)] public float maxRestriction = 0.7f;
|
|
|
|
+ public float maxRestrictionChangePerSecond = 0.8f;
|
|
|
|
+
|
|
|
|
+ [Tooltip("Depending on Vignetting source -> deg or deg/s")]
|
|
|
|
+ public float threshold = 20f;
|
|
|
|
|
|
//TODO: figure out what angular velocity means in my context
|
|
//TODO: figure out what angular velocity means in my context
|
|
private MaterialBlitFeature blitFeature;
|
|
private MaterialBlitFeature blitFeature;
|
|
private Material blitFeatureMaterial;
|
|
private Material blitFeatureMaterial;
|
|
private bool blitFeatureAvailable;
|
|
private bool blitFeatureAvailable;
|
|
|
|
|
|
- private QueueBasedRestrictionSuggestor leaningAngleSuggestor;
|
|
|
|
- private QueueBasedRestrictionSuggestor hmdAngleSuggestor;
|
|
|
|
|
|
+ private ValueBasedRestrictionSuggestor steerAngleSuggestor;
|
|
|
|
+ private QueueBasedRestrictionSuggestorVector3 angularVelocitySuggestor;
|
|
|
|
+ private float currentRestriction;
|
|
|
|
|
|
private void Start()
|
|
private void Start()
|
|
{
|
|
{
|
|
blitFeature = (MaterialBlitFeature) forwardRenderer.rendererFeatures.FirstOrDefault(f =>
|
|
blitFeature = (MaterialBlitFeature) forwardRenderer.rendererFeatures.FirstOrDefault(f =>
|
|
f is MaterialBlitFeature && f.name.Equals("VignetteBlitFilter"));
|
|
f is MaterialBlitFeature && f.name.Equals("VignetteBlitFilter"));
|
|
blitFeatureAvailable = blitFeature != null;
|
|
blitFeatureAvailable = blitFeature != null;
|
|
|
|
+
|
|
if (!blitFeatureAvailable) return;
|
|
if (!blitFeatureAvailable) return;
|
|
|
|
+ // ReSharper disable once PossibleNullReferenceException
|
|
blitFeatureMaterial = blitFeature.settings.MaterialToBlit;
|
|
blitFeatureMaterial = blitFeature.settings.MaterialToBlit;
|
|
|
|
+
|
|
|
|
+ if (vignettingSource == VignettingSource.AngularVelocity)
|
|
|
|
+ {
|
|
|
|
+ angularVelocitySuggestor =
|
|
|
|
+ new QueueBasedRestrictionSuggestorVector3(threshold, minRestriction, maxRestriction, 180f); //deg/s
|
|
|
|
+ }
|
|
|
|
+ else if (vignettingSource == VignettingSource.SteerAngle)
|
|
|
|
+ {
|
|
|
|
+ steerAngleSuggestor =
|
|
|
|
+ new ValueBasedRestrictionSuggestor(threshold: threshold, minRestriction, maxRestriction,
|
|
|
|
+ bikeController.maxSteeringAngle); //deg
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private void Update()
|
|
private void Update()
|
|
{
|
|
{
|
|
if (!blitFeatureAvailable) return;
|
|
if (!blitFeatureAvailable) return;
|
|
- if (Mathf.Abs(bikeController.CurrentSteerAngle) >= steerAngleThreshold)
|
|
|
|
|
|
+
|
|
|
|
+ float desiredRestriction;
|
|
|
|
+
|
|
|
|
+ if (vignettingSource == VignettingSource.AngularVelocity)
|
|
|
|
+ {
|
|
|
|
+ angularVelocitySuggestor.AddValue(bikeController.rigidBody.transform.localEulerAngles);
|
|
|
|
+ desiredRestriction = angularVelocitySuggestor.Suggestion;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ steerAngleSuggestor.Value = bikeController.CurrentSteerAngle;
|
|
|
|
+ desiredRestriction = steerAngleSuggestor.Suggestion;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var desiredChange = desiredRestriction - currentRestriction;
|
|
|
|
+ var maxChange = Time.deltaTime * maxRestrictionChangePerSecond;
|
|
|
|
+ var change = Mathf.Sign(desiredChange) * Mathf.Min(Mathf.Abs(desiredChange), maxChange);
|
|
|
|
+ var correctedRestriction = Mathf.Clamp(currentRestriction + change, 0, 1);
|
|
|
|
+
|
|
|
|
+ Debug.Log("V: CurrentRestriction = " + currentRestriction);
|
|
|
|
+ Debug.Log("V: DesiredChange = " + desiredChange);
|
|
|
|
+ Debug.Log("V: MaxChange = " + maxChange);
|
|
|
|
+ Debug.Log("V: DesiredRestriction = " + desiredRestriction);
|
|
|
|
+ Debug.Log("V: CorrectedRestriction = " + correctedRestriction);
|
|
|
|
+
|
|
|
|
+ if (correctedRestriction > 0f)
|
|
{
|
|
{
|
|
blitFeature.SetActive(true);
|
|
blitFeature.SetActive(true);
|
|
- UpdateMaterial(.6f); //TODO: no magic number
|
|
|
|
|
|
+ UpdateMaterial(correctedRestriction);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- //TODO: figure out how to combine everything
|
|
|
|
blitFeature.SetActive(false);
|
|
blitFeature.SetActive(false);
|
|
}
|
|
}
|
|
|
|
|
|
private void UpdateMaterial(float restriction)
|
|
private void UpdateMaterial(float restriction)
|
|
{
|
|
{
|
|
|
|
+ currentRestriction = restriction;
|
|
var r = Mathf.Clamp(1 - restriction, 0, 1);
|
|
var r = Mathf.Clamp(1 - restriction, 0, 1);
|
|
blitFeatureMaterial.SetFloat("_OFOV", r);
|
|
blitFeatureMaterial.SetFloat("_OFOV", r);
|
|
blitFeatureMaterial.SetFloat("_IFOV", Mathf.Clamp(r - DIST_IFOV_OVOF, 0, 1));
|
|
blitFeatureMaterial.SetFloat("_IFOV", Mathf.Clamp(r - DIST_IFOV_OVOF, 0, 1));
|