Unity3D研究院之动态分辨率降低渲染开销

之前项目降低分辨率我们都普遍使用Screen.SetResolution,但是它有两个问题。

1.每次设置的时候屏幕会闪烁。

2.降低分辨率与摄像机无关,无法做到只降低3D摄像机的分辨率,保留UI摄像机不降低分辨率。

其实我们可以使用摄像机动态分辨率,如下图所示,给需要降低分辨率的摄像机打开allow Dynamic Resolution属性。

 

如下图所示,在ProjectSetting上必须勾选Enable Frame Timing Stats属性。

 

代码中就可以很方便设置分辨率了。

1

    ScalableBufferManager.ResizeBuffers(m_widthScale, m_heightScale);

如下图所示在iPhone X上,频繁设置3D摄像机分辨率并不会出现闪烁的情况,而且并没有影响UI摄像机看到的文本(Text)的分辨率

 

需要注意的是动态分辨率安卓Android(仅适用于Vulkan) 或者也可以用SRP可编程渲染管线,最后在修改RT这样就都支持了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

 

public class DynamicResolutionTest : MonoBehaviour

{

    public Text screenText;

 

    FrameTiming[] frameTimings = new FrameTiming[3];

 

    public float maxResolutionWidthScale = 1.0f;

    public float maxResolutionHeightScale = 1.0f;

    public float minResolutionWidthScale = 0.5f;

    public float minResolutionHeightScale = 0.5f;

    public float scaleWidthIncrement = 0.1f;

    public float scaleHeightIncrement = 0.1f;

 

    float m_widthScale = 1.0f;

    float m_heightScale = 1.0f;

 

    // Variables for dynamic resolution algorithm that persist across frames

    uint m_frameCount = 0;

 

    const uint kNumFrameTimings = 2;

 

    double m_gpuFrameTime;

    double m_cpuFrameTime;

 

    // Use this for initialization

    void Start()

    {

        int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width);

        int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height);

        screenText.text = string.Format("Scale: {0:F3}x{1:F3}\nResolution: {2}x{3}\n",

            m_widthScale,

            m_heightScale,

            rezWidth,

            rezHeight);

    }

 

 

    private void OnGUI()

    {

        float oldWidthScale = m_widthScale;

        float oldHeightScale = m_heightScale;

 

        // One finger lowers the resolution

        if (GUILayout.Button("<size=100>--</size>"))

        {

            m_heightScale = Mathf.Max(minResolutionHeightScale, m_heightScale - scaleHeightIncrement);

            m_widthScale = Mathf.Max(minResolutionWidthScale, m_widthScale - scaleWidthIncrement);

        }

 

        // Two fingers raises the resolution

        if (GUILayout.Button("<size=100>++</size>"))

        {

            m_heightScale = Mathf.Min(maxResolutionHeightScale, m_heightScale + scaleHeightIncrement);

            m_widthScale = Mathf.Min(maxResolutionWidthScale, m_widthScale + scaleWidthIncrement);

        }

 

        if (m_widthScale != oldWidthScale || m_heightScale != oldHeightScale)

        {

            ScalableBufferManager.ResizeBuffers(m_widthScale, m_heightScale);

        }

    }

    // Update is called once per frame

    void Update()

    {

        

        DetermineResolution();

        int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width);

        int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height);

        screenText.text = string.Format("Scale: {0:F3}x{1:F3}\n动态分辨率: {2}x{3}\nScaleFactor: {4:F3}x{5:F3}\nGPU: {6:F3} CPU: {7:F3}",

            m_widthScale,

            m_heightScale,

            rezWidth,

            rezHeight,

            ScalableBufferManager.widthScaleFactor,

            ScalableBufferManager.heightScaleFactor,

            m_gpuFrameTime,

            m_cpuFrameTime);

    }

 

    // Estimate the next frame time and update the resolution scale if necessary.

    private void DetermineResolution()

    {

        ++m_frameCount;

        if (m_frameCount <= kNumFrameTimings)

        {

            return;

        }

        FrameTimingManager.CaptureFrameTimings();

        FrameTimingManager.GetLatestTimings(kNumFrameTimings, frameTimings);

        if (frameTimings.Length < kNumFrameTimings)

        {

            Debug.LogFormat("Skipping frame {0}, didn't get enough frame timings.",

                m_frameCount);

 

            return;

        }

 

        m_gpuFrameTime = (double)frameTimings[0].gpuFrameTime;

        m_cpuFrameTime = (double)frameTimings[0].cpuFrameTime;

    }

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值