From 9d9bf8b8bf11413bf622910d208939fb56ad2ce9 Mon Sep 17 00:00:00 2001 From: Yannick Date: Sat, 1 Apr 2017 09:53:40 +0200 Subject: [PATCH 1/2] Added distortion correction when RenderMananger is not available --- .../Assets/OSVRUnity/src/DisplayController.cs | 52 ++++++++- .../Assets/OSVRUnity/src/OsvrDistortion.cs | 107 ++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs diff --git a/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs b/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs index 4bea018..89db336 100644 --- a/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs +++ b/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs @@ -43,7 +43,6 @@ namespace Unity //*/ public class DisplayController : MonoBehaviour { - public const uint NUM_VIEWERS = 1; private const int TARGET_FRAME_RATE = 60; //@todo get from OSVR @@ -282,6 +281,8 @@ private void CreateHeadAndEyes() } } + var distortionParams = GetDistortionParams(); + // loop through viewers because at some point we could support multiple viewers // but this implementation currently supports exactly one for (; viewerIndex < _viewerCount; viewerIndex++) @@ -301,12 +302,61 @@ private void CreateHeadAndEyes() _viewers[viewerIndex] = vrViewerComponent; vrViewer.tag = "MainCamera"; + if (!_useRenderManager && viewerIndex < distortionParams.Length) + { + var disto = vrViewer.gameObject.AddComponent(); + disto.K1Red = distortionParams[viewerIndex].x; + disto.K1Green = distortionParams[viewerIndex].y; + disto.K1Blue = distortionParams[viewerIndex].z; + } + // create Viewer's VREyes uint eyeCount = (uint)_displayConfig.GetNumEyesForViewer(viewerIndex); //get the number of eyes for this viewer vrViewerComponent.CreateEyes(eyeCount); } } + private Vector3[] GetDistortionParams() + { + var numViewers = _displayConfig.GetNumViewers(); + var distortionParams = new Vector3[2]; + + if (numViewers != 1) + throw new UnityException("[OSVR] Only one viewer supported."); + + for (uint viewer = 0; viewer < numViewers; viewer++) + { + var numEyes = _displayConfig.GetNumEyesForViewer(viewer); + if (numEyes != 2) + throw new UnityException("[OSVR] Two eyes are required, not less, not more."); + + for (byte eye = 0; eye < numEyes; eye++) + { + var numSurfaces = _displayConfig.GetNumSurfacesForViewerEye(viewer, eye); + if (numSurfaces != 1) + throw new UnityException("[OSVR] A surface is required."); + + for (uint surface = 0; surface < numSurfaces; surface++) + { + var distortionCorrectionRequired = _displayConfig.DoesViewerEyeSurfaceWantDistortion(viewer, eye, surface); + if (distortionCorrectionRequired) + { + var radialDistortionPriority = _displayConfig.GetViewerEyeSurfaceRadialDistortionPriority(viewer, eye, surface); + if (radialDistortionPriority >= 0) + { + var dist = _displayConfig.GetViewerEyeSurfaceRadialDistortion(viewer, eye, surface); + distortionParams[eye].x = (float)dist.k1.x; + distortionParams[eye].y = (float)dist.k1.y; + distortionParams[eye].z = (float)dist.k1.z; + } + } + } + } + } + + return distortionParams; + } + void Update() { // sometimes it takes a few frames to get a DisplayConfig from ClientKit diff --git a/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs b/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs new file mode 100644 index 0000000..8b5b510 --- /dev/null +++ b/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs @@ -0,0 +1,107 @@ +using UnityEngine; + +namespace OSVR.Unity +{ + [ExecuteInEditMode] + [RequireComponent(typeof(Camera))] + public sealed class OsvrDistortion : MonoBehaviour + { + private bool isSupported = true; + private Material distortionMaterial = null; + private Shader distortionShader = null; + + public float K1Red = 0.0f; + public float K1Green = 0.0f; + public float K1Blue = 0.0f; + public Vector4 Center = new Vector4(0.5f, 0.5f, 0.0f, 0.0f); + + private void Start() + { + CheckResources(); + } + + private void OnEnable() + { + isSupported = true; + } + + private void OnRenderImage(RenderTexture source, RenderTexture destination) + { + if (CheckResources() == false) + { + Graphics.Blit(source, destination); + return; + } + + distortionMaterial.SetFloat("_K1_Red", K1Red); + distortionMaterial.SetFloat("_K1_Green", K1Green); + distortionMaterial.SetFloat("_K1_Blue", K1Blue); + distortionMaterial.SetVector("_Center", Center); + Graphics.Blit(source, destination, distortionMaterial); + } + + private Material CheckShaderAndCreateMaterial(Shader shader, Material materialToCreate) + { + shader = distortionShader = Shader.Find("Osvr/OsvrDistortion"); + + if (!shader) + { + Debug.Log("Missing shader in " + ToString()); + enabled = false; + return null; + } + + if (shader.isSupported && materialToCreate && materialToCreate.shader == shader) + return materialToCreate; + + if (!shader.isSupported) + { + NotSupported(); + Debug.Log("The shader " + shader.ToString() + " on effect " + ToString() + " is not supported on this platform!"); + return null; + } + else + { + materialToCreate = new Material(shader); + materialToCreate.hideFlags = HideFlags.DontSave; + + if (materialToCreate) + return materialToCreate; + else + return null; + } + } + + private bool CheckResources() + { + CheckSupport(); + + distortionMaterial = CheckShaderAndCreateMaterial(distortionShader, distortionMaterial); + + if (!isSupported) + Debug.LogWarning("The image effect " + ToString() + " has been disabled as it's not supported on the current platform."); + + return isSupported; + } + + private bool CheckSupport() + { + isSupported = true; + + if (!SystemInfo.supportsImageEffects) + { + NotSupported(); + return false; + } + + return true; + } + + private void NotSupported() + { + enabled = false; + isSupported = false; + return; + } + } +} \ No newline at end of file From 4c26519dd03d444aa4052cae18d6655b1c88a33e Mon Sep 17 00:00:00 2001 From: Yannick Date: Sat, 1 Apr 2017 13:45:35 +0200 Subject: [PATCH 2/2] Applying the distortion on VREye --- .../Assets/OSVRUnity/src/DisplayController.cs | 51 --------- .../Assets/OSVRUnity/src/OsvrDistortion.cs | 107 ------------------ OSVR-Unity/Assets/OSVRUnity/src/VREye.cs | 47 +++++--- 3 files changed, 30 insertions(+), 175 deletions(-) delete mode 100644 OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs diff --git a/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs b/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs index 89db336..0b81fb1 100644 --- a/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs +++ b/OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs @@ -281,8 +281,6 @@ private void CreateHeadAndEyes() } } - var distortionParams = GetDistortionParams(); - // loop through viewers because at some point we could support multiple viewers // but this implementation currently supports exactly one for (; viewerIndex < _viewerCount; viewerIndex++) @@ -302,61 +300,12 @@ private void CreateHeadAndEyes() _viewers[viewerIndex] = vrViewerComponent; vrViewer.tag = "MainCamera"; - if (!_useRenderManager && viewerIndex < distortionParams.Length) - { - var disto = vrViewer.gameObject.AddComponent(); - disto.K1Red = distortionParams[viewerIndex].x; - disto.K1Green = distortionParams[viewerIndex].y; - disto.K1Blue = distortionParams[viewerIndex].z; - } - // create Viewer's VREyes uint eyeCount = (uint)_displayConfig.GetNumEyesForViewer(viewerIndex); //get the number of eyes for this viewer vrViewerComponent.CreateEyes(eyeCount); } } - private Vector3[] GetDistortionParams() - { - var numViewers = _displayConfig.GetNumViewers(); - var distortionParams = new Vector3[2]; - - if (numViewers != 1) - throw new UnityException("[OSVR] Only one viewer supported."); - - for (uint viewer = 0; viewer < numViewers; viewer++) - { - var numEyes = _displayConfig.GetNumEyesForViewer(viewer); - if (numEyes != 2) - throw new UnityException("[OSVR] Two eyes are required, not less, not more."); - - for (byte eye = 0; eye < numEyes; eye++) - { - var numSurfaces = _displayConfig.GetNumSurfacesForViewerEye(viewer, eye); - if (numSurfaces != 1) - throw new UnityException("[OSVR] A surface is required."); - - for (uint surface = 0; surface < numSurfaces; surface++) - { - var distortionCorrectionRequired = _displayConfig.DoesViewerEyeSurfaceWantDistortion(viewer, eye, surface); - if (distortionCorrectionRequired) - { - var radialDistortionPriority = _displayConfig.GetViewerEyeSurfaceRadialDistortionPriority(viewer, eye, surface); - if (radialDistortionPriority >= 0) - { - var dist = _displayConfig.GetViewerEyeSurfaceRadialDistortion(viewer, eye, surface); - distortionParams[eye].x = (float)dist.k1.x; - distortionParams[eye].y = (float)dist.k1.y; - distortionParams[eye].z = (float)dist.k1.z; - } - } - } - } - } - - return distortionParams; - } - void Update() { // sometimes it takes a few frames to get a DisplayConfig from ClientKit diff --git a/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs b/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs deleted file mode 100644 index 8b5b510..0000000 --- a/OSVR-Unity/Assets/OSVRUnity/src/OsvrDistortion.cs +++ /dev/null @@ -1,107 +0,0 @@ -using UnityEngine; - -namespace OSVR.Unity -{ - [ExecuteInEditMode] - [RequireComponent(typeof(Camera))] - public sealed class OsvrDistortion : MonoBehaviour - { - private bool isSupported = true; - private Material distortionMaterial = null; - private Shader distortionShader = null; - - public float K1Red = 0.0f; - public float K1Green = 0.0f; - public float K1Blue = 0.0f; - public Vector4 Center = new Vector4(0.5f, 0.5f, 0.0f, 0.0f); - - private void Start() - { - CheckResources(); - } - - private void OnEnable() - { - isSupported = true; - } - - private void OnRenderImage(RenderTexture source, RenderTexture destination) - { - if (CheckResources() == false) - { - Graphics.Blit(source, destination); - return; - } - - distortionMaterial.SetFloat("_K1_Red", K1Red); - distortionMaterial.SetFloat("_K1_Green", K1Green); - distortionMaterial.SetFloat("_K1_Blue", K1Blue); - distortionMaterial.SetVector("_Center", Center); - Graphics.Blit(source, destination, distortionMaterial); - } - - private Material CheckShaderAndCreateMaterial(Shader shader, Material materialToCreate) - { - shader = distortionShader = Shader.Find("Osvr/OsvrDistortion"); - - if (!shader) - { - Debug.Log("Missing shader in " + ToString()); - enabled = false; - return null; - } - - if (shader.isSupported && materialToCreate && materialToCreate.shader == shader) - return materialToCreate; - - if (!shader.isSupported) - { - NotSupported(); - Debug.Log("The shader " + shader.ToString() + " on effect " + ToString() + " is not supported on this platform!"); - return null; - } - else - { - materialToCreate = new Material(shader); - materialToCreate.hideFlags = HideFlags.DontSave; - - if (materialToCreate) - return materialToCreate; - else - return null; - } - } - - private bool CheckResources() - { - CheckSupport(); - - distortionMaterial = CheckShaderAndCreateMaterial(distortionShader, distortionMaterial); - - if (!isSupported) - Debug.LogWarning("The image effect " + ToString() + " has been disabled as it's not supported on the current platform."); - - return isSupported; - } - - private bool CheckSupport() - { - isSupported = true; - - if (!SystemInfo.supportsImageEffects) - { - NotSupported(); - return false; - } - - return true; - } - - private void NotSupported() - { - enabled = false; - isSupported = false; - return; - } - } -} \ No newline at end of file diff --git a/OSVR-Unity/Assets/OSVRUnity/src/VREye.cs b/OSVR-Unity/Assets/OSVRUnity/src/VREye.cs index de0dc23..44c28e4 100644 --- a/OSVR-Unity/Assets/OSVRUnity/src/VREye.cs +++ b/OSVR-Unity/Assets/OSVRUnity/src/VREye.cs @@ -40,8 +40,8 @@ public class VREye : MonoBehaviour private VRSurface[] _surfaces; //the surfaces associated with this eye private uint _surfaceCount; private uint _eyeIndex; - - + + #endregion #region Public Variables public uint EyeIndex @@ -49,7 +49,7 @@ public uint EyeIndex get { return _eyeIndex; } set { _eyeIndex = value; } } - public VRSurface[] Surfaces { get { return _surfaces; } } + public VRSurface[] Surfaces { get { return _surfaces; } } public uint SurfaceCount { get { return _surfaceCount; } } public VRViewer Viewer { @@ -75,7 +75,7 @@ void Init() { //cache: cachedTransform = transform; - } + } #endregion // Updates the position and rotation of the eye @@ -122,7 +122,7 @@ public void UpdateSurfaces() //get projection matrix from RenderManager and set surface projection matrix surface.SetProjectionMatrix(Viewer.DisplayController.RenderManager.GetEyeProjectionMatrix((int)EyeIndex)); - + surface.Render(); } else @@ -145,7 +145,7 @@ public void UpdateSurfaces() //render the surface surface.Render(); - } + } } } @@ -209,7 +209,7 @@ public void CreateSurfaces(uint surfaceCount) //get distortion parameters OSVR.ClientKit.RadialDistortionParameters distortionParameters = Viewer.DisplayController.DisplayConfig.GetViewerEyeSurfaceRadialDistortion( - Viewer.ViewerIndex, (byte)_eyeIndex, surfaceIndex); + Viewer.ViewerIndex, (byte)_eyeIndex, surfaceIndex); surface.SetDistortion(distortionParameters); } @@ -229,6 +229,8 @@ public void CreateSurfaces(uint surfaceCount) } } + var displayController = FindObjectOfType(); + //loop through surfaces because at some point we could support eyes with multiple surfaces //but this implementation currently supports exactly one @@ -247,20 +249,31 @@ public void CreateSurfaces(uint surfaceCount) //distortion bool useDistortion = Viewer.DisplayController.DisplayConfig.DoesViewerEyeSurfaceWantDistortion(Viewer.ViewerIndex, (byte)_eyeIndex, surfaceIndex); - if(useDistortion) + useDistortion |= !displayController.UseRenderManager; + + if (useDistortion) { //@todo figure out which type of distortion to use //right now, there is only one option, SurfaceRadialDistortion //get distortion parameters - OSVR.ClientKit.RadialDistortionParameters distortionParameters = - Viewer.DisplayController.DisplayConfig.GetViewerEyeSurfaceRadialDistortion( - Viewer.ViewerIndex, (byte)_eyeIndex, surfaceIndex); + OSVR.ClientKit.RadialDistortionParameters distortionParameters; + + try + { + distortionParameters = Viewer.DisplayController.DisplayConfig.GetViewerEyeSurfaceRadialDistortion(Viewer.ViewerIndex, (byte)_eyeIndex, surfaceIndex); + } + catch (Exception ex) + { + // The previous call fails, so we use the minimal distortion parameters to ensure a better experience. + distortionParameters.centerOfProjection = new OSVR.ClientKit.Vec2() { x = 0.5, y = 0.5 }; + distortionParameters.k1 = new OSVR.ClientKit.Vec3() { x = 0.25, y = 0.25, z = 0.25 }; + } surface.SetDistortion(distortionParameters); - } - + } + //render manager - if(Viewer.DisplayController.UseRenderManager) + if (Viewer.DisplayController.UseRenderManager) { //Set the surfaces viewport from RenderManager surface.SetViewport(Viewer.DisplayController.RenderManager.GetEyeViewport((int)EyeIndex)); @@ -271,8 +284,8 @@ public void CreateSurfaces(uint surfaceCount) { renderTexture.antiAliasing = QualitySettings.antiAliasing; } - surface.SetRenderTexture(renderTexture); - } + surface.SetRenderTexture(renderTexture); + } } } @@ -284,7 +297,7 @@ private void CopyCamera(Camera srcCamera, Camera destCamera) destCamera.CopyFrom(srcCamera); destCamera.depth = 0; //@todo Copy other components attached to the DisplayController? - } + } } } }