眼球追踪技术 Unity+ HTC vive Pro + DroolonF1 (三)

英伟达VRS,通过改变帧的不同区域的着色速率来提高渲染性能和质量。

下载SDK:Unity 应用商店>> Vive Foveated Rendering 

眼球追踪技术 Unity+ HTC vive Pro + DroolonF1 (三)_第1张图片

 导入插件:在摄像机上挂载ViveFoveatedRendering脚本 勾选Manual Adjustment  选择适合自己的渲染方式

这个脚本我用Google翻译了一下

//========= Copyright 2020, HTC Corporation. All rights reserved. ===========

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.XR;
using System;

namespace HTC.UnityPlugin.FoveatedRendering
{
    public static class FoveatedRenderingExtensions
    {
        public static T Clamp(this T input, T min, T max) where T : IComparable
        {
            if (min.CompareTo(input) > 0)
            { return min; }
            else if (max.CompareTo(input) < 0)
            { return max; }

            return input;
        }
    }

    [RequireComponent(typeof(Camera))]
    public class ViveFoveatedRendering : MonoBehaviour
    {
        Camera thisCamera = null;
        CommandBufferManager commandBufferMgr = new CommandBufferManager();

        bool foveatedRenderingInited = false;
        bool foveatedRenderingActivated = false;
        RenderMode renderMode = RenderMode.RENDER_MODE_MONO;

        [SerializeField][Header("手动调整")]
        bool manualAdjustment = false;

        [SerializeField][Header("阴影率预设")]
        ShadingRatePreset shadingRatePreset = ShadingRatePreset.SHADING_RATE_HIGHEST_PERFORMANCE;
        [SerializeField][Header("模式预设")]
        ShadingPatternPreset patternPreset = ShadingPatternPreset.SHADING_PATTERN_NARROW;

        [SerializeField][Header("内区半径")]
        Vector2 innerRegionRadii = new Vector2(0.25f, 0.25f);
        [SerializeField][Header("中区半径")]
        Vector2 middleRegionRadii = new Vector2(0.33f, 0.33f);
        [SerializeField][Header("外区半径")]
        Vector2 peripheralRegionRadii = new Vector2(1.0f, 1.0f);

        [SerializeField]
        [Header("内区阴影")]
        ShadingRate innerShadingRate = ShadingRate.X1_PER_PIXEL;
        [SerializeField]
        [Header("中区阴影")]
        ShadingRate middleShadingRate = ShadingRate.X1_PER_2X2_PIXELS;
        [SerializeField]
        [Header("外区阴影")]
        ShadingRate peripheralShadingRate = ShadingRate.X1_PER_4X4_PIXELS;

        /// 
        /// 启用中心渲染
        /// 
        /// 
        public void EnableFoveatedRendering(bool activate)
        {
            if (foveatedRenderingInited && activate != foveatedRenderingActivated)
            {
                foveatedRenderingActivated = activate;
                if (activate)
                {
                    commandBufferMgr.EnableCommands(thisCamera);
                }
                else
                {
                    commandBufferMgr.DisableCommands(thisCamera);
                }
            }
        }


        /// 
        /// 设置阴影率预设
        /// 
        /// 
        public void SetShadingRatePreset(ShadingRatePreset inputPreset)
        {
            if (foveatedRenderingInited)
            {
                shadingRatePreset = inputPreset.Clamp(ShadingRatePreset.SHADING_RATE_HIGHEST_PERFORMANCE, ShadingRatePreset.SHADING_RATE_MAX);
                ViveFoveatedRenderingAPI.SetFoveatedRenderingShadingRatePreset(shadingRatePreset);

                if (shadingRatePreset == ShadingRatePreset.SHADING_RATE_CUSTOM)
                {
                    SetShadingRate(TargetArea.INNER, innerShadingRate);
                    SetShadingRate(TargetArea.MIDDLE, middleShadingRate);
                    SetShadingRate(TargetArea.PERIPHERAL, peripheralShadingRate);
                }

                GL.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.UPDATE_GAZE);
            }
        }

        /// 
        /// 阴影率预设
        /// 
        /// 
        public ShadingRatePreset GetShadingRatePreset()
        {
            return shadingRatePreset;
        }


        /// 
        /// 设置模式预设
        /// 
        /// 
        public void SetPatternPreset(ShadingPatternPreset inputPreset)
        {
            if (foveatedRenderingInited)
            {
                patternPreset = inputPreset.Clamp(ShadingPatternPreset.SHADING_PATTERN_WIDE, ShadingPatternPreset.SHADING_PATTERN_MAX);
                ViveFoveatedRenderingAPI.SetFoveatedRenderingPatternPreset(patternPreset);

                if (patternPreset == ShadingPatternPreset.SHADING_PATTERN_CUSTOM)
                {
                    SetRegionRadii(TargetArea.INNER, innerRegionRadii);
                    SetRegionRadii(TargetArea.MIDDLE, middleRegionRadii);
                    SetRegionRadii(TargetArea.PERIPHERAL, peripheralRegionRadii);
                }

                GL.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.UPDATE_GAZE);
            }
        }

        /// 
        /// 阴影模式预设
        /// 
        /// 
        public ShadingPatternPreset GetPatternPreset()
        {
            return patternPreset;
        }

        /// 
        /// 设置阴影
        /// 
        /// 
        /// 
        public void SetShadingRate(TargetArea targetArea, ShadingRate rate)
        {
            if (foveatedRenderingInited)
            {
                var clampedRate = rate.Clamp(ShadingRate.CULL, ShadingRate.X1_PER_4X4_PIXELS);
                switch (targetArea)
                {
                    case TargetArea.INNER:
                        innerShadingRate = clampedRate;
                        break;
                    case TargetArea.MIDDLE:
                        middleShadingRate = clampedRate;
                        break;
                    case TargetArea.PERIPHERAL:
                        peripheralShadingRate = clampedRate;
                        break;
                }

                ViveFoveatedRenderingAPI.SetShadingRate(targetArea, clampedRate);
                GL.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.UPDATE_GAZE);
            }
        }

        
        /// 
        /// 阴影
        /// 
        /// 
        /// 
        public ShadingRate GetShadingRate(TargetArea targetArea)
        {
            switch (targetArea)
            {
                case TargetArea.INNER:
                    return innerShadingRate;
                case TargetArea.MIDDLE:
                    return middleShadingRate;
                case TargetArea.PERIPHERAL:
                    return peripheralShadingRate;
            }

            return ShadingRate.CULL;
        }

        /// 
        /// 设置区域半径
        /// 
        /// 
        /// 
        public void SetRegionRadii(TargetArea targetArea, Vector2 radii)
        {
            if (foveatedRenderingInited)
            {
                var clampedRadii = new Vector2(radii.x.Clamp(0.01f, 10.0f), radii.y.Clamp(0.01f, 10.0f));
                switch (targetArea)
                {
                    case TargetArea.INNER:
                        innerRegionRadii = clampedRadii;
                        break;
                    case TargetArea.MIDDLE:
                        middleRegionRadii = clampedRadii;
                        break;
                    case TargetArea.PERIPHERAL:
                        peripheralRegionRadii = clampedRadii;
                        break;
                }

                ViveFoveatedRenderingAPI.SetRegionRadii(targetArea, clampedRadii);
                GL.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.UPDATE_GAZE);
            }
        }


        /// 
        /// 获取区域半径
        /// 
        /// 
        /// 
        public Vector2 GetRegionRadii(TargetArea targetArea)
        {
            switch (targetArea)
            {
                case TargetArea.INNER:
                    return innerRegionRadii;
                case TargetArea.MIDDLE:
                    return middleRegionRadii;
                case TargetArea.PERIPHERAL:
                    return peripheralRegionRadii;
            }

            return Vector2.zero;
        }


        void OnEnable()
        {
			ViveFoveatedRenderingAPI.InitializeNativeLogger(str => Debug.Log(str));

            thisCamera = GetComponent();
            foveatedRenderingInited = ViveFoveatedRenderingAPI.InitializeFoveatedRendering(thisCamera.fieldOfView, thisCamera.aspect);
            if (foveatedRenderingInited)
            {
                var currentRenderingPath = thisCamera.actualRenderingPath;
                if (currentRenderingPath == RenderingPath.Forward)
                {
                    commandBufferMgr.AppendCommands("Enable Foveated Rendering", CameraEvent.BeforeForwardOpaque,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.ENABLE_FOVEATED_RENDERING),
                        buf => buf.ClearRenderTarget(false, true, Color.black));

                    commandBufferMgr.AppendCommands("Disable Foveated Rendering", CameraEvent.AfterForwardAlpha,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.DISABLE_FOVEATED_RENDERING));
                }
                else if (currentRenderingPath == RenderingPath.DeferredShading)
                {
                    commandBufferMgr.AppendCommands("Enable Foveated Rendering - GBuffer", CameraEvent.BeforeGBuffer,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.ENABLE_FOVEATED_RENDERING),
                        buf => buf.ClearRenderTarget(false, true, Color.black));

                    commandBufferMgr.AppendCommands("Disable Foveated Rendering - GBuffer", CameraEvent.AfterGBuffer,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.DISABLE_FOVEATED_RENDERING));

                    commandBufferMgr.AppendCommands("Enable Foveated Rendering - Alpha", CameraEvent.BeforeForwardAlpha,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.ENABLE_FOVEATED_RENDERING));

                    commandBufferMgr.AppendCommands("Disable Foveated Rendering - Alpha", CameraEvent.AfterForwardAlpha,
                        buf => buf.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.DISABLE_FOVEATED_RENDERING));
                }
                
                EnableFoveatedRendering(true);
                bool isEyeTracked = ViveFoveatedGazeUpdater.AttachGazeUpdater(gameObject);
                if (manualAdjustment || (!ViveFoveatedInitParam.SetParamByHMD(this, isEyeTracked)))
                {
                    SetShadingRatePreset(shadingRatePreset);
                    SetPatternPreset(patternPreset);
                }

                ViveFoveatedRenderingAPI.SetNormalizedGazeDirection(new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, 0.0f, 1.0f));
                GL.IssuePluginEvent(ViveFoveatedRenderingAPI.GetRenderEventFunc(), (int)EventID.UPDATE_GAZE);
            }
        }


        void OnDisable()
        {
            EnableFoveatedRendering(false);
            commandBufferMgr.ClearCommands();
			
			ViveFoveatedRenderingAPI.ReleaseFoveatedRendering();
            ViveFoveatedRenderingAPI.ReleaseNativeLogger();

            foveatedRenderingInited = false;

            var gazeUpdater = GetComponent();
            if (gazeUpdater != null)
            {
                gazeUpdater.enabled = false;
            }
        }

        void OnPreRender()
        {
            if (XRSettings.enabled)
            {
                switch (XRSettings.stereoRenderingMode)
                {
                    case XRSettings.StereoRenderingMode.MultiPass:
                        renderMode = thisCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Left ?
                        RenderMode.RENDER_MODE_LEFT_EYE : RenderMode.RENDER_MODE_RIGHT_EYE;
                        break;
                    case XRSettings.StereoRenderingMode.SinglePass:
                        renderMode = RenderMode.RENDER_MODE_STEREO;
                        break;
                    default:
                        renderMode = RenderMode.RENDER_MODE_MONO;
                        break;
                }
            }
            else
            {
                renderMode = RenderMode.RENDER_MODE_MONO;
            }

            ViveFoveatedRenderingAPI.SetRenderMode(renderMode);
        }
    }
}

 

你可能感兴趣的:(HTC,Vive,DroolonF1,Unity)