Unity 检测手机性能,区分高中低端机型(URP)

有兴趣可查看之前写的标准渲染管线的版本

适配了URP渲染管线,并增加了抛弃第一次采样的数据(涉及Shader编译会影响采样数据)

可设置隔帧采样不影响游戏运行

一般在游戏启动进登录界面时可以开始,Camera设置为场景相机

 注意:

Maximum Sample Counter和Draw Times Per Batch不宜设置太高,否则可能出现在UPR或者UWA报告中看到DrawCall和面数超高的情况

Mesh最好在500面左右

using Logic;
using Sirenix.OdinInspector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.Rendering;

public class GPUPerformanceTest : MonoBehaviour
{
    public Camera Camera;
    public Material Material;
    public Mesh Mesh;

    RenderTexture texture;

    float startTestTime;
    int sampleCounter;
    int skipCounter;
    public int skipSample = 1; // 丢弃采样,第一次渲染可能涉及shader编译,会影响统计数据
    public int maximumSampleCounter = 5;
    public int DrawTimesPerBatch = 100;
    public int BatchCountPerFrame = 1;
    public int FrameTimeMS = 10;
    public int DelayFramePerTest = 5;

    public float ScoreScale = 1;
    public float ScoreAdjust = 0;

    //public int MaximumDrawCount = 5000;

    long elapsedMS;

    [HideInInspector]
    public float TestScore = 0;// 性能测试评分

    private int _TotalDrawTimes = 0;
    private long _TotalDrawMilliseconds = 0;

    int delayFrameCounter;

    public bool RunOnStart = true;

    public Action OnComplete;

    enum TestState
    {
        Waiting,
        Tasting,
        Delaying,
        Completed,
        Freeze,
    }

    TestState State;

    private void Awake()
    {
        State = TestState.Waiting;
    }
    private void Start()
    {
        if (RunOnStart)
        {
            StartTest();
        }
    }
    [Button]
    public void StartTest()
    {
        sampleCounter = 0;
        skipCounter = 0;
        delayFrameCounter = 0;
        startTestTime = Time.realtimeSinceStartup;

        if (!this.gameObject.activeSelf)
        {
            this.gameObject.SetActive(true);
        }

        State = TestState.Tasting;
        Common.Log.Info("Performance test begin-------------");
    }

    private void OnEnable()
    {
        //texture = RenderTexture.GetTemporary(Camera.pixelWidth, Camera.pixelHeight, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.R16G16B16A16_SFloat);

        RenderPipelineManager.endCameraRendering += RenderPipelineManager_endCameraRendering;

    }
    void TestDrawMesh()
    {
        long milliseconds = 0;
        int draw_times = 0;

        var stopwatch = Stopwatch.StartNew();
        for (int n = 0; n < BatchCountPerFrame; ++n)
        {
            {

                for (int i = 0; i < DrawTimesPerBatch; ++i)
                {
                    CommandBuffer commandBuffer = new CommandBuffer();

                    Vector3 look = this.Camera.transform.TransformDirection(Vector3.forward);
                    Vector3 pos = this.Camera.transform.position + look.normalized * 10;
                    RenderTargetIdentifier targetIdentifier = new RenderTargetIdentifier(texture);
                    commandBuffer.DrawMesh(Mesh, Matrix4x4.TRS(pos, Quaternion.identity, Vector3.one), Material);

                    Graphics.ExecuteCommandBuffer(commandBuffer);

                    draw_times++;
                }
            }

            if (stopwatch.ElapsedMilliseconds > FrameTimeMS)
            {
                break;
            }

            //             if (_TotalDrawTimes >= MaximumDrawCount)
            //             {
            //                 break;
            //             }
        }
        stopwatch.Stop();

        milliseconds = stopwatch.ElapsedMilliseconds;

        _TotalDrawTimes += draw_times;
        _TotalDrawMilliseconds += milliseconds;
    }
    private void RenderPipelineManager_endCameraRendering(ScriptableRenderContext arg1, Camera arg2)
    {
        if (State != TestState.Tasting)
            return;

        TestDrawMesh();

        sampleCounter++;

        if (skipCounter < skipSample)
        {
            skipCounter++;

            sampleCounter = 0;
            _TotalDrawTimes = 0;
            _TotalDrawMilliseconds = 0;
        }

        if (sampleCounter >= maximumSampleCounter)
        //if (_TotalDrawTimes >= MaximumDrawCount)
        {
            State = TestState.Completed;
        }
        else
        {
            delayFrameCounter = 0;
            State = TestState.Delaying;
        }
    }

    private void Update()
    {
        switch (State)
        {
            case TestState.Delaying:
                {
                    if (delayFrameCounter >= DelayFramePerTest)
                    {
                        State = TestState.Tasting;
                    }
                    delayFrameCounter++;
                }
                break;
            case TestState.Completed:
                {
                    TestScore = 1.0f * _TotalDrawTimes / Mathf.Max(1, _TotalDrawMilliseconds);
                    TestScore = TestScore * ScoreScale + ScoreAdjust;

                    Common.Log.Info($"Performance test draw mesh time(MS): {_TotalDrawMilliseconds}, draw times: {_TotalDrawTimes}, score: {TestScore}. ({Time.realtimeSinceStartup - startTestTime}s");

                    State = TestState.Freeze;

                    OnComplete?.Invoke();
                }
                break;
            case TestState.Freeze:
                {
                    this.gameObject.SetActive(false);
                }
                break;
        }
    }
    private void OnDisable()
    {
        RenderPipelineManager.endCameraRendering -= RenderPipelineManager_endCameraRendering;

        //RenderTexture.ReleaseTemporary(texture);
    }
}

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值