环境
Unity: 2018.2.11f1
Pipeline: BRP
Platform : Android
Graphics API : OpenGL ES 3/+
Color Space : Linear
问题
部分移动设备的 GPU 精度比较低,会导致精度表现不佳的异常显示
(本来想用 RenderDoc, Snapdragon Profiler 来查看真机的 FB 的格式,但是这两个工具都越来越不给力了,市场上能用的真机抓帧工具越来越少,基本上现在能用的就只用 RenderDoc抓PC,Intel GPA抓PC,Snapdragon Profiler 只能抓高通机型的部分应用:必须开启 debuggable, read/write permission 要开启才能抓,但是 Snapdragon Profiler很多BUG,经常崩溃、闪退,或是无法显示 Pixel History 数据,现在这些大厂,或是主流工具都这么不给力了吗?-_-!!!)
比如:
- 软粒子与 opaque 内容 fade 过度异常
- 水体与 opaque 内容的 深度 fade 过度异常
(经过一番测试,最终无法解决,还好未来新项目使用的是URP)
测试 Shader 部分代码
// depth gradient control foam
float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
float fragZ = i.projPos.z;
// return sceneZ;
// return fragZ;
float detalZ = sceneZ-fragZ;
return saturate(detalZ); // 这里再:oppo, vivo 的低端手机中,会有精度丢失严重的问题,导致,PC上 和 低端设备上 效果差异很大
测试 C#
// jave.lin : 2022/06/29
// 测试 水体深度颜色过度异常的问题
// 后来定位到是:深度精度问题
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
public class Test_WaterReflectionError_Script : MonoBehaviour {
public Text graphicsAPI_Text;
// jave.lin : 之前我的: Unity - 画质设置 https://blog.csdn.net/linjf520/article/details/123546253
// 文章中列出的打印
public static string DumpSystemInfoByManualyPrint()
{
var list = new List<string>(
new string[]{
"SystemInfo:\n",
"\tbatteryLevel:" + SystemInfo.batteryLevel,
"\tbatteryStatus:" + SystemInfo.batteryStatus,
"\toperatingSystem:" + SystemInfo.operatingSystem,
"\toperatingSystemFamily:" + SystemInfo.operatingSystemFamily,
"\tprocessorType:" + SystemInfo.processorType,
"\tprocessorFrequency:" + SystemInfo.processorFrequency,
"\tprocessorCount:" + SystemInfo.processorCount,
"\tsystemMemorySize:" + SystemInfo.systemMemorySize,
"\tdeviceUniqueIdentifier:" + SystemInfo.deviceUniqueIdentifier,
"\tdeviceName:" + SystemInfo.deviceName,
"\tdeviceModel:" + SystemInfo.deviceModel,
"\tsupportsAccelerometer:" + SystemInfo.supportsAccelerometer,
"\tsupportsGyroscope:" + SystemInfo.supportsGyroscope,
"\tsupportsLocationService:" + SystemInfo.supportsLocationService,
"\tsupportsVibration:" + SystemInfo.supportsVibration,
"\tsupportsAudio:" + SystemInfo.supportsAudio,
"\tdeviceType:" + SystemInfo.deviceType,
"\tgraphicsMemorySize:" + SystemInfo.graphicsMemorySize,
"\tgraphicsDeviceName:" + SystemInfo.graphicsDeviceName,
"\tgraphicsDeviceVendor:" + SystemInfo.graphicsDeviceVendor,
"\tgraphicsDeviceID:" + SystemInfo.graphicsDeviceID,
"\tgraphicsDeviceVendorID:" + SystemInfo.graphicsDeviceVendorID,
"\tgraphicsDeviceType:" + SystemInfo.graphicsDeviceType,
"\tgraphicsUVStartsAtTop:" + SystemInfo.graphicsUVStartsAtTop,
"\tgraphicsDeviceVersion:" + SystemInfo.graphicsDeviceVersion,
"\tgraphicsShaderLevel:" + SystemInfo.graphicsShaderLevel,
"\tgraphicsMultiThreaded:" + SystemInfo.graphicsMultiThreaded,
"\tsupportsShadows:" + SystemInfo.supportsShadows,
"\tsupportsRawShadowDepthSampling:" + SystemInfo.supportsRawShadowDepthSampling,
"\tsupportsMotionVectors:" + SystemInfo.supportsMotionVectors,
"\tsupports3DTextures:" + SystemInfo.supports3DTextures,
"\tsupports2DArrayTextures:" + SystemInfo.supports2DArrayTextures,
"\tsupports3DRenderTextures:" + SystemInfo.supports3DRenderTextures,
"\tsupportsCubemapArrayTextures:" + SystemInfo.supportsCubemapArrayTextures,
"\tcopyTextureSupport:" + SystemInfo.copyTextureSupport,
"\tsupportsComputeShaders:" + SystemInfo.supportsComputeShaders,
"\tsupportsInstancing:" + SystemInfo.supportsInstancing,
"\tsupportsHardwareQuadTopology:" + SystemInfo.supportsHardwareQuadTopology,
"\tsupports32bitsIndexBuffer:" + SystemInfo.supports32bitsIndexBuffer,
"\tsupportsSparseTextures:" + SystemInfo.supportsSparseTextures,
"\tsupportedRenderTargetCount:" + SystemInfo.supportedRenderTargetCount,
"\tsupportsMultisampledTextures:" + SystemInfo.supportsMultisampledTextures,
"\tsupportsMultisampleAutoResolve:" + SystemInfo.supportsMultisampleAutoResolve,
"\tsupportsTextureWrapMirrorOnce:" + SystemInfo.supportsTextureWrapMirrorOnce,
"\tusesReversedZBuffer:" + SystemInfo.usesReversedZBuffer,
"\tnpotSupport:" + SystemInfo.npotSupport,
"\tmaxTextureSize:" + SystemInfo.maxTextureSize,
"\tmaxCubemapSize:" + SystemInfo.maxCubemapSize,
"\tsupportsAsyncCompute:" + SystemInfo.supportsAsyncCompute,
"\tsupportsAsyncGPUReadback:" + SystemInfo.supportsAsyncGPUReadback,
"\tsupportsMipStreaming:" + SystemInfo.supportsMipStreaming,
});
return string.Join("\n", list.ToArray());
}
// jave.lin : 现在我们调试的话,只需要部分的即可
public static string MyDump()
{
var list = new List<string>(
new string[]{
"SystemInfo:\n",
"\toperatingSystem:" + SystemInfo.operatingSystem,
"\toperatingSystemFamily:" + SystemInfo.operatingSystemFamily,
"\tdeviceName:" + SystemInfo.deviceName,
"\tdeviceType:" + SystemInfo.deviceType,
"\tgraphicsMemorySize:" + SystemInfo.graphicsMemorySize,
"\tgraphicsDeviceName:" + SystemInfo.graphicsDeviceName,
"\tgraphicsDeviceVendor:" + SystemInfo.graphicsDeviceVendor,
"\tgraphicsDeviceType:" + SystemInfo.graphicsDeviceType,
"\tgraphicsDeviceVersion:" + SystemInfo.graphicsDeviceVersion,
"\tgraphicsShaderLevel:" + SystemInfo.graphicsShaderLevel,
"\tsupportsComputeShaders:" + SystemInfo.supportsComputeShaders,
"\tsupportsInstancing:" + SystemInfo.supportsInstancing,
"\tusesReversedZBuffer:" + SystemInfo.usesReversedZBuffer,
});
return string.Join("\n", list.ToArray());
}
// Use this for initialization
void Start () {
graphicsAPI_Text.text = MyDump();
}
}
各个设备中的表现
Unity 编辑中
夜神模拟器中
小米10
OPPO A5
可以看到 OPPO A5 是显示异常的
BRP 中没看到有相关的解决
毕竟 BRP 是未来不推荐的方案
所以出现这种问题,建议还是使用 URP
本来想看看 project setting 中的 graphics, quality 有无相关的深度精度设置,经过一番搜索与项目配置查找,都没有找到相关内容
- goolgle : how to improve precision in unity shaderlab
然后在 官方文档中 Cameras and depth textures 找到一些精度相关的说明
查找过的配置:
- ProjectSetting->Player->OtherSetting->Rendering - 没有相关
- ProjectSetting->Player->OtherSetting->Resolution and Presentation - 没有相关
- ProjectSetting->Graphics 下尝试将所有的 Tier Settings 都设置到最高,也不行
- Shader 中添加:
#pragma fragmentoption ARB_precision_hint_nicest
也不行 - Shader 中修改
_CameraDepthTexture
为float
的纹理采样器设置也不行,比如:uniform sampler2D_float _CameraDepthTexture;
URP 中有解决
这写问题在 早期的 URP 也有出现,比如这帖子:Android depth texture precision issue. - 帖主是再:Unity 2019.3.6f1 URP 7.2.1,在 URP:7.4.1 修复了
大概就是:application 层,对 _CameraDepthTexture
的纹理对象格式的设置(精度设置)
还有 shader 中的精度声明
在 BRP 中并没有对应的可控性,这在 URP 是可控的,所以 URP 可以解决此问题
另外,高版本的 unity 也看到有:shader precision mode 的设置
下面是:2022.1.4f1 的截图
导致这些精度问题,一般还与 Camera 的 近截面,远截面 的差值有关,差值越大,那么越容易出现这个问题
而这个项目在我来之前,他们的模型比例等相关制作的缩放都是异常的,比如:500 scale,x,y,z
然后 Camera 的 near plane, far plane 都只能设置很大,比如:near : 0.1, far : 10000,那么精度的值肯定大大受限
References
- Android depth texture precision issue. - 帖主是再:Unity 2019.3.6f1 URP 7.2.1,在 URP:7.4.1 修复了