コード例 #1
0
        private void UpdateRenderScale()
        {
            if (!scaleRenderViewport)
            {
                renderViewportScaleSetting.currentValue = defaultRenderViewportScaleLevel;
                renderScaleSetting.currentValue         = defaultRenderViewportScaleLevel;
                SetRenderScale(1.0f, 1.0f);

                return;
            }

            // Rendering in low resolution means adaptive quality needs to scale back the render scale target to free up gpu cycles
            bool renderInLowResolution = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources();

            // Thresholds
            float allowedSingleFrameDurationInMilliseconds = renderInLowResolution
                                                             ? singleFrameDurationInMilliseconds * 0.75f
                                                             : singleFrameDurationInMilliseconds;
            float lowThresholdInMilliseconds           = 0.7f * allowedSingleFrameDurationInMilliseconds;
            float extrapolationThresholdInMilliseconds = 0.85f * allowedSingleFrameDurationInMilliseconds;
            float highThresholdInMilliseconds          = 0.9f * allowedSingleFrameDurationInMilliseconds;

            int newRenderViewportScaleLevel = renderViewportScaleSetting.currentValue;

            // Rapidly reduce render viewport scale level if cost of last 1 or 3 frames, or the predicted next frame's cost are expensive
            if (timing.WasFrameTimingBad(
                    1,
                    highThresholdInMilliseconds,
                    renderViewportScaleSetting.lastChangeFrameCount,
                    renderViewportScaleSetting.decreaseFrameCost) ||
                timing.WasFrameTimingBad(
                    3,
                    highThresholdInMilliseconds,
                    renderViewportScaleSetting.lastChangeFrameCount,
                    renderViewportScaleSetting.decreaseFrameCost) ||
                timing.WillFrameTimingBeBad(
                    extrapolationThresholdInMilliseconds,
                    highThresholdInMilliseconds,
                    renderViewportScaleSetting.lastChangeFrameCount,
                    renderViewportScaleSetting.decreaseFrameCost))
            {
                // Always drop 2 levels except when dropping from level 2 (level 0 is for reprojection)
                newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue == 2
                                                                    ? 1
                                                                    : renderViewportScaleSetting.currentValue - 2);
            }
            // Rapidly increase render viewport scale level if last 12 frames are cheap
            else if (timing.WasFrameTimingGood(
                         12,
                         lowThresholdInMilliseconds,
                         renderViewportScaleSetting.lastChangeFrameCount - renderViewportScaleSetting.increaseFrameCost,
                         renderViewportScaleSetting.increaseFrameCost))
            {
                newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue + 2);
            }
            // Slowly increase render viewport scale level if last 6 frames are cheap
            else if (timing.WasFrameTimingGood(
                         6,
                         lowThresholdInMilliseconds,
                         renderViewportScaleSetting.lastChangeFrameCount,
                         renderViewportScaleSetting.increaseFrameCost))
            {
                // Only increase by 1 level to prevent frame drops caused by adjusting
                newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue + 1);
            }

            // Apply and remember when render viewport scale level changed
            if (newRenderViewportScaleLevel != renderViewportScaleSetting.currentValue)
            {
                if (renderViewportScaleSetting.currentValue >= renderScaleSetting.currentValue &&
                    newRenderViewportScaleLevel < renderScaleSetting.currentValue)
                {
                    lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount = Time.frameCount;
                }

                renderViewportScaleSetting.currentValue = newRenderViewportScaleLevel;
            }

            // Ignore frame timings if overriding
            if (overrideRenderViewportScale)
            {
                renderViewportScaleSetting.currentValue = overrideRenderViewportScaleLevel;
            }

            // Force on interleaved reprojection for level 0 which is just a replica of level 1 with reprojection enabled
            float additionalViewportScale = 1.0f;

            if (!hmdDisplayIsOnDesktop)
            {
                if (renderViewportScaleSetting.currentValue == 0)
                {
                    if (interleavedReprojectionEnabled && timing.GetFrameTiming(0) < singleFrameDurationInMilliseconds * 0.85f)
                    {
                        interleavedReprojectionEnabled = false;
                    }
                    else if (timing.GetFrameTiming(0) > singleFrameDurationInMilliseconds * 0.925f)
                    {
                        interleavedReprojectionEnabled = true;
                    }
                }
                else
                {
                    interleavedReprojectionEnabled = false;
                }

                VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(interleavedReprojectionEnabled);
            }
            // Not running in direct mode! Interleaved reprojection not supported, so scale down the viewport some more
            else if (renderViewportScaleSetting.currentValue == 0)
            {
                additionalViewportScale = 0.8f;
            }

            int newRenderScaleLevel = renderScaleSetting.currentValue;
            int levelInBetween      = (renderViewportScaleSetting.currentValue - renderScaleSetting.currentValue) / 2;

            // Increase render scale level to the level in between
            if (renderScaleSetting.currentValue < renderViewportScaleSetting.currentValue &&
                Time.frameCount >= renderScaleSetting.lastChangeFrameCount + renderScaleSetting.increaseFrameCost)
            {
                newRenderScaleLevel = ClampRenderScaleLevel(renderScaleSetting.currentValue + Mathf.Max(1, levelInBetween));
            }
            // Decrease render scale level
            else if (renderScaleSetting.currentValue > renderViewportScaleSetting.currentValue &&
                     Time.frameCount >= renderScaleSetting.lastChangeFrameCount + renderScaleSetting.decreaseFrameCost &&
                     Time.frameCount >= lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount + renderViewportScaleSetting.increaseFrameCost)
            {
                // Slowly decrease render scale level to level in between if last 6 frames are cheap, otherwise rapidly
                newRenderScaleLevel = timing.WasFrameTimingGood(6, lowThresholdInMilliseconds, 0, 0)
                                      ? ClampRenderScaleLevel(renderScaleSetting.currentValue + Mathf.Min(-1, levelInBetween))
                                      : renderViewportScaleSetting.currentValue;
            }

            // Apply and remember when render scale level changed
            renderScaleSetting.currentValue = newRenderScaleLevel;

            if (!scaleRenderTargetResolution)
            {
                renderScaleSetting.currentValue = allRenderScales.Count - 1;
            }

            float newRenderScale         = allRenderScales[renderScaleSetting.currentValue];
            float newRenderViewportScale = allRenderScales[Mathf.Min(renderViewportScaleSetting.currentValue, renderScaleSetting.currentValue)]
                                           / newRenderScale * additionalViewportScale;

            SetRenderScale(newRenderScale, newRenderViewportScale);
        }
コード例 #2
0
        private void UpdateRenderScale()
        {
            if (!active)
            {
                SetRenderScale(1.0f, 1.0f);
                return;
            }

            // Add latest timing to ring buffer
            frameTimeRingBufferIndex = (frameTimeRingBufferIndex + 1) % frameTimeRingBuffer.Length;
            frameTimeRingBuffer[frameTimeRingBufferIndex] = UnityEngine.XR.XRStats.gpuTimeLastFrame;

            // Rendering in low resolution means adaptive quality needs to scale back the render scale target to free up gpu cycles
            bool renderInLowResolution = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources();

            // Thresholds
            float thresholdModifier = renderInLowResolution
                                      ? singleFrameDurationInMilliseconds * 0.75f
                                      : singleFrameDurationInMilliseconds;
            float lowThresholdInMilliseconds           = 0.7f * thresholdModifier;
            float extrapolationThresholdInMilliseconds = 0.85f * thresholdModifier;
            float highThresholdInMilliseconds          = 0.9f * thresholdModifier;

            // Get latest 3 frames
            float frameMinus0 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 0 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length];
            float frameMinus1 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 1 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length];
            float frameMinus2 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 2 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length];

            int previousLevel = currentRenderScaleLevel;

            // Always drop 2 levels except when dropping from level 2
            int dropTargetLevel = previousLevel == 2 ? 1 : previousLevel - 2;
            int newLevel        = Mathf.Clamp(dropTargetLevel, 0, allRenderScales.Count - 1);

            // Ignore frame timings if overriding
            if (overrideRenderScale)
            {
                currentRenderScaleLevel = overrideRenderScaleLevel;
            }
            // Rapidly reduce quality 2 levels if last frame was critical
            else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 1 &&
                     frameMinus0 > highThresholdInMilliseconds &&
                     newLevel != previousLevel)
            {
                currentRenderScaleLevel         = newLevel;
                lastRenderScaleChangeFrameCount = Time.frameCount;
            }
            // Rapidly reduce quality 2 levels if last 3 frames are expensive
            else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3 &&
                     frameMinus0 > highThresholdInMilliseconds &&
                     frameMinus1 > highThresholdInMilliseconds &&
                     frameMinus2 > highThresholdInMilliseconds &&
                     newLevel != previousLevel)
            {
                currentRenderScaleLevel         = newLevel;
                lastRenderScaleChangeFrameCount = Time.frameCount;
            }
            // Predict next frame's cost using linear extrapolation: max(frame-1 to frame+1, frame-2 to frame+1)
            else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 2 &&
                     frameMinus0 > extrapolationThresholdInMilliseconds)
            {
                float frameDelta = frameMinus0 - frameMinus1;

                // Use frame-2 if it's available
                if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3)
                {
                    float frameDelta2 = (frameMinus0 - frameMinus2) * 0.5f;
                    frameDelta = Mathf.Max(frameDelta, frameDelta2);
                }

                if (frameMinus0 + frameDelta > highThresholdInMilliseconds &&
                    newLevel != previousLevel)
                {
                    currentRenderScaleLevel         = newLevel;
                    lastRenderScaleChangeFrameCount = Time.frameCount;
                }
            }
            else
            {
                // Increase quality 1 level if last 3 frames are cheap
                newLevel = Mathf.Clamp(previousLevel + 1, 0, allRenderScales.Count - 1);
                if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3 &&
                    frameMinus0 < lowThresholdInMilliseconds &&
                    frameMinus1 < lowThresholdInMilliseconds &&
                    frameMinus2 < lowThresholdInMilliseconds &&
                    newLevel != previousLevel)
                {
                    currentRenderScaleLevel         = newLevel;
                    lastRenderScaleChangeFrameCount = Time.frameCount;
                }
            }

            // Force on interleaved reprojection for level 0 which is just a replica of level 1 with reprojection enabled
            float additionalViewportScale = 1.0f;

            if (!hmdDisplayIsOnDesktop)
            {
                if (currentRenderScaleLevel == 0)
                {
                    if (interleavedReprojectionEnabled && frameMinus0 < singleFrameDurationInMilliseconds * 0.85f)
                    {
                        interleavedReprojectionEnabled = false;
                    }
                    else if (frameMinus0 > singleFrameDurationInMilliseconds * 0.925f)
                    {
                        interleavedReprojectionEnabled = true;
                    }
                }
                else
                {
                    interleavedReprojectionEnabled = false;
                }

                VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(interleavedReprojectionEnabled);
            }
            // Not running in direct mode! Interleaved reprojection not supported, so scale down the viewport
            else if (currentRenderScaleLevel == 0)
            {
                additionalViewportScale = 0.8f;
            }

            float newRenderScale         = allRenderScales[allRenderScales.Count - 1];
            float newRenderViewportScale = allRenderScales[currentRenderScaleLevel] / newRenderScale * additionalViewportScale;

            SetRenderScale(newRenderScale, newRenderViewportScale);
        }
コード例 #3
0
        // Token: 0x06001B91 RID: 7057 RVA: 0x00090340 File Offset: 0x0008E540
        private void UpdateRenderScale()
        {
            if (this.allRenderScales.Count == 0)
            {
                return;
            }
            if (!this.scaleRenderViewport)
            {
                this.renderViewportScaleSetting.currentValue = this.defaultRenderViewportScaleLevel;
                this.renderScaleSetting.currentValue         = this.defaultRenderViewportScaleLevel;
                VRTK_AdaptiveQuality.SetRenderScale(1f, 1f);
                return;
            }
            float num = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources() ? (this.singleFrameDurationInMilliseconds * 0.75f) : this.singleFrameDurationInMilliseconds;
            float thresholdInMilliseconds = 0.7f * num;
            float extrapolationThresholdInMilliseconds = 0.85f * num;
            float thresholdInMilliseconds2             = 0.9f * num;
            int   num2 = this.renderViewportScaleSetting.currentValue;

            if (this.timing.WasFrameTimingBad(1, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost) || this.timing.WasFrameTimingBad(3, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost) || this.timing.WillFrameTimingBeBad(extrapolationThresholdInMilliseconds, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost))
            {
                num2 = this.ClampRenderScaleLevel((this.renderViewportScaleSetting.currentValue == 2) ? 1 : (this.renderViewportScaleSetting.currentValue - 2));
            }
            else if (this.timing.WasFrameTimingGood(12, thresholdInMilliseconds, this.renderViewportScaleSetting.lastChangeFrameCount - this.renderViewportScaleSetting.increaseFrameCost, this.renderViewportScaleSetting.increaseFrameCost))
            {
                num2 = this.ClampRenderScaleLevel(this.renderViewportScaleSetting.currentValue + 2);
            }
            else if (this.timing.WasFrameTimingGood(6, thresholdInMilliseconds, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.increaseFrameCost))
            {
                num2 = this.ClampRenderScaleLevel(this.renderViewportScaleSetting.currentValue + 1);
            }
            if (num2 != this.renderViewportScaleSetting.currentValue)
            {
                if (this.renderViewportScaleSetting.currentValue >= this.renderScaleSetting.currentValue && num2 < this.renderScaleSetting.currentValue)
                {
                    this.lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount = Time.frameCount;
                }
                this.renderViewportScaleSetting.currentValue = num2;
            }
            if (this.overrideRenderViewportScale)
            {
                this.renderViewportScaleSetting.currentValue = this.overrideRenderViewportScaleLevel;
            }
            float num3 = 1f;

            if (!this.hmdDisplayIsOnDesktop)
            {
                if (this.renderViewportScaleSetting.currentValue == 0)
                {
                    if (this.interleavedReprojectionEnabled && this.timing.GetFrameTiming(0) < this.singleFrameDurationInMilliseconds * 0.85f)
                    {
                        this.interleavedReprojectionEnabled = false;
                    }
                    else if (this.timing.GetFrameTiming(0) > this.singleFrameDurationInMilliseconds * 0.925f)
                    {
                        this.interleavedReprojectionEnabled = true;
                    }
                }
                else
                {
                    this.interleavedReprojectionEnabled = false;
                }
                VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(this.interleavedReprojectionEnabled);
            }
            else if (this.renderViewportScaleSetting.currentValue == 0)
            {
                num3 = 0.8f;
            }
            int currentValue = this.renderScaleSetting.currentValue;
            int b            = (this.renderViewportScaleSetting.currentValue - this.renderScaleSetting.currentValue) / 2;

            if (this.renderScaleSetting.currentValue < this.renderViewportScaleSetting.currentValue && Time.frameCount >= this.renderScaleSetting.lastChangeFrameCount + this.renderScaleSetting.increaseFrameCost)
            {
                currentValue = this.ClampRenderScaleLevel(this.renderScaleSetting.currentValue + Mathf.Max(1, b));
            }
            else if (this.renderScaleSetting.currentValue > this.renderViewportScaleSetting.currentValue && Time.frameCount >= this.renderScaleSetting.lastChangeFrameCount + this.renderScaleSetting.decreaseFrameCost && Time.frameCount >= this.lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount + this.renderViewportScaleSetting.increaseFrameCost)
            {
                currentValue = (this.timing.WasFrameTimingGood(6, thresholdInMilliseconds, 0, 0) ? this.ClampRenderScaleLevel(this.renderScaleSetting.currentValue + Mathf.Min(-1, b)) : this.renderViewportScaleSetting.currentValue);
            }
            this.renderScaleSetting.currentValue = currentValue;
            if (!this.scaleRenderTargetResolution)
            {
                this.renderScaleSetting.currentValue = this.allRenderScales.Count - 1;
            }
            float num4 = this.allRenderScales[this.renderScaleSetting.currentValue];
            float renderViewportScale = this.allRenderScales[Mathf.Min(this.renderViewportScaleSetting.currentValue, this.renderScaleSetting.currentValue)] / num4 * num3;

            VRTK_AdaptiveQuality.SetRenderScale(num4, renderViewportScale);
        }