• Unity Shader - 踩坑 - BRP 管线中的 depth texture 的精度问题(暂无解决方案,推荐换 URP)



    环境

    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上 和 低端设备上 效果差异很大
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试 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();
        }
    }
    
    
    • 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

    各个设备中的表现


    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 中修改 _CameraDepthTexturefloat 的纹理采样器设置也不行,比如: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

  • 相关阅读:
    Flask--认识flask与环境准备
    Java技能树-RE-元字符-贪婪模式/非贪婪模式
    第九章 动态规划 part13 300. 最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
    对遗留系统的处理——(一)系统评价
    121. 一键部署开箱即用的代理服务器,解决 SAP UI5 应用开发过程中访问远端 OData 服务的跨域问题
    ReentrantReadWriteLock读写锁实现原理详解
    CAS与原子类
    self-attention、transformer、bert理解
    asp.net上传文件
    【图像处理OpenCV(C++版)】——初学OpenCV
  • 原文地址:https://blog.csdn.net/linjf520/article/details/125522428