目录
1、ScreenCapture.CaptureScreenshot
最近在跑测的过程中需要保存unity的截图信息 遂对几种截图方法进行测试 找到性能消耗最低的方案
1、ScreenCapture.CaptureScreenshot
使用Unity官方提供的截图函数
每0.2s进行一次截图 性能如下:
2、使用协程ReadPixels
在这里加上锁 防止截图频率过高 内存泄漏导致项目崩溃 代码如下:
IEnumerator screenShotCoroutine1(string path)
{
if (isCapturing)
yield break; // 如果正在捕获,直接返回
isCapturing = true;
yield return new WaitForEndOfFrame();
UnityEngine.Debug.Log(path);
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
screenImage.Apply();
byte[] rawData = screenImage.EncodeToJPG();
File.WriteAllBytes(path, rawData);
isCapturing = false; // 重置状态
}
每0.2s进行一次截图 性能如下:
3、使用协程ReadPixels + 多线程保存图片
用线程的话不能用unity的API 所以我这里仅在保存的时候开多线程 将上面协程函数最后的保存部分替换为下述内容
new System.Threading.Thread(() =>
{
//System.Threading.Thread.Sleep(100);
File.WriteAllBytes(path, rawData);
}).Start();
每0.2s进行一次截图 性能如下:
4、结论
使用协程ReadPixels效果最好
代码链接:
5、使用方法二的额外性能开销
有截图:
无截图:
具体的差异报告:
{
"captureInfo": {
"current": {
"capturePath": "無截圖.apc",
"captureDuration": "146.47s",
"processAnalyzed": "com.DefaultCompany.perfetto (pid: 17320)",
"reportGeneratedAt": "13 5月 2025 14:10",
"version": "Performance Advisor 9.5.1 (Build 9.5.1.v20250318_1203)"
},
"previous": {
"capturePath": "截圖每秒一張.apc",
"captureDuration": "141.05s",
"processAnalyzed": "com.DefaultCompany.perfetto (pid: 12280)",
"reportGeneratedAt": "13 5月 2025 14:05",
"version": "Performance Advisor 9.5.1 (Build 9.5.1.v20250318_1203)"
}
},
"fpsBoundness": {
"frameRate": {
"average": 0.9,
"max": -2.2,
"min": 4.7,
"centiles": {
"80": 0.1,
"98": -1.6,
"95": -0.5
}
},
"msPerFrame": {
"average": 1.4,
"max": -6.0,
"min": 0.0,
"centiles": {
"80": -2.3,
"98": -5.3,
"95": -4.8
}
}
},
"cpuCyclesPerFrame": {
"cpuUsage": {
"average": -7400931.9,
"max": -64843489.1,
"min": 193519.1,
"centiles": {
"80": -8371937.6,
"98": -24756628.3,
"95": -19784454.9
}
}
},
"gpuUsagePerFrame": {
"gpuCycles": {
"average": -141048.4,
"max": -278671.1,
"min": -8492.6,
"centiles": {
"80": -112224.1,
"98": -182022.1,
"95": -160256.9
}
},
"fragmentCycles": {
"average": -2954109.2,
"max": -5794839.3,
"min": -268647.2,
"centiles": {
"80": -2436461.4,
"98": -3989238.0,
"95": -3579593.0
}
},
"nonfragmentCycles": {
"average": 34103.4,
"max": -16862.2,
"min": 6283.1,
"centiles": {
"80": 42974.0,
"98": 40554.6,
"95": 43578.7
}
}
},
"shaderCoreValhallPerFrame": {
"arithmeticCycles": {
"average": -1905.8,
"max": -11930.4,
"min": -3600.9,
"centiles": {
"80": 2811.3,
"98": -4338.0,
"95": -822.0
}
},
"loadstoreCycles": {
"average": -12.0,
"max": -167.6,
"min": 4.3,
"centiles": {
"80": 13.7,
"98": -49.4,
"95": -10.1
}
},
"varyingCycles": {
"average": 149.9,
"max": -10991.0,
"min": 28161.5,
"centiles": {
"80": 2240.4,
"98": -4909.7,
"95": -1373.9
}
},
"textureCycles": {
"average": -2807.2,
"max": -1485.7,
"min": 18613.9,
"centiles": {
"80": -57.8,
"98": -4074.2,
"95": -2091.7
}
}
},
"verticesPerFrame": {
"vertices": {
"average": -7.3,
"max": -14.6,
"min": 0.8,
"centiles": {
"80": -3.8,
"98": -6.4,
"95": -3.4
}
}
},
"primitivesPerFrame": {
"totalPrimitives": {
"average": -55.6,
"max": -126.6,
"min": 0.8,
"centiles": {
"80": -27.3,
"98": -52.4,
"95": -22.9
}
},
"visiblePrimitives": {
"average": -7.3,
"max": -14.6,
"min": 0.8,
"centiles": {
"80": -3.8,
"98": -6.4,
"95": -3.4
}
}
},
"pixelsPerFrame": {
"pixels": {
"average": -228525.1,
"max": -1051624.5,
"min": 1485110.7,
"centiles": {
"80": 116747.5,
"98": -445688.9,
"95": -107615.7
}
}
},
"gpuBandwidthPerFrame": {
"externalReadBytes": {
"average": -10149863.9,
"max": -11968506.7,
"min": -197049.0,
"centiles": {
"80": -9719453.0,
"98": -11140624.8,
"95": -10575712.6
}
},
"externalWriteBytes": {
"average": -1045105.1,
"max": -2988564.1,
"min": -222605.1,
"centiles": {
"80": -725070.3,
"98": -3288498.0,
"95": -3193380.2
}
},
"totalExternalBytes": {
"average": -5597484.5,
"max": -6800043.9,
"min": -403775.1,
"centiles": {
"80": -5145184.6,
"98": -7182190.8,
"95": -6772143.8
}
}
},
"overdrawPerPixel": {
"overdraw": {
"average": 0.0,
"max": -0.1,
"min": 0.0,
"centiles": {
"80": 0.0,
"98": -0.2,
"95": -0.2
}
}
}
}
6、现有方案
Udacity和NVIDIA有一个项目
https://github.com/udacity/self-driving-car-sim
可以参考他们代码中的1_SelfDrivingCar/scripts/camera helper.cs
using UnityEngine;
public static class CameraHelper
{
public static byte[] CaptureFrame(Camera camera)
{
RenderTexture targetTexture = camera.targetTexture;
RenderTexture.active = targetTexture;
Texture2D texture2D = new Texture2D(targetTexture.width, targetTexture.height, TextureFormat.RGB24, false);
texture2D.ReadPixels(new Rect(0, 0, targetTexture.width, targetTexture.height), 0, 0);
texture2D.Apply();
byte[] image = texture2D.EncodeToJPG();
Object.DestroyImmediate(texture2D); // Required to prevent leaking the texture
return image;
}
}