Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG

这篇具有很好参考价值的文章主要介绍了Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


环境

Unity : 2020.3.37f1
Pipeline : BRP


目的

备忘,便于日后索引


问题

正常手机显卡芯片的浮点解析进度上的效果(其实不用手机上,PC 上将 uv * scale 一个巨大的值也会出现的)
Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG

异常手机显卡芯片的浮点解析进度上的效果(其实不用手机上,PC 上将 uv * scale 一个巨大的值也会出现的)
Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG


解决

诊断发现是: UV 精度 scale 之后溢出了

这个 shader 是 网上的一位TA大佬 (听说是叫: 猫大 的TA大佬 写的,下面的 shader 可以看到是使用 ASE 连连看 生成的代码)

// Made with Amplify Shader Editor
// Available at the Unity Asset Store - http://u3d.as/y3X 
Shader "VFX/PandaShaderSampleV1.0"
{
	Properties
	{
		[Enum(UnityEngine.Rendering.BlendMode)]_Scr("Scr", Float) = 5
		[Enum(UnityEngine.Rendering.BlendMode)]_Dst("Dst", Float) = 10
		[Enum(UnityEngine.Rendering.CullMode)]_CullMode("CullMode", Float) = 0
		_MainTex("MainTex", 2D) = "white" {}
		[Toggle]_MainTexAR("MainTexAR", Float) = 0
		[HDR]_MainColor("MainColor", Color) = (1,1,1,1)
		_MainTexUSpeed("MainTexUSpeed", Float) = 0
		_MainTexVSpeed("MainTexVSpeed", Float) = 0
		[Toggle]_CustomMainTex("CustomMainTex", Float) = 0
		[Toggle(_FMASKTEX_ON)] _FMaskTex("FMaskTex", Float) = 0
		_MaskTex("MaskTex", 2D) = "white" {}
		[Toggle]_MaskTexAR("MaskTexAR", Float) = 1
		_MaskTexUSpeed("MaskTexUSpeed", Float) = 0
		_MaskTexVSpeed("MaskTexVSpeed", Float) = 0
		[Toggle(_FDISTORTTEX_ON)] _FDistortTex("FDistortTex", Float) = 0
		_DistortTex("DistortTex", 2D) = "white" {}
		[Toggle]_DistortTexAR("DistortTexAR", Float) = 1
		_DistortFactor("DistortFactor", Range( 0 , 1)) = 0
		_DistortTexUSpeed("DistortTexUSpeed", Float) = 0
		_DistortTexVSpeed("DistortTexVSpeed", Float) = 0
		[Toggle]_DistortMainTex("DistortMainTex", Float) = 0
		[Toggle]_DistortMaskTex("DistortMaskTex", Float) = 0
		[Toggle]_DistortDissolveTex("DistortDissolveTex", Float) = 0
		[Toggle(_FDISSOLVETEX_ON)] _FDissolveTex("FDissolveTex", Float) = 0
		_DissolveTex("DissolveTex", 2D) = "white" {}
		[Toggle]_DissolveTexAR("DissolveTexAR", Float) = 1
		[HDR]_DissolveColor("DissolveColor", Color) = (1,1,1,1)
		[Toggle]_CustomDissolve("CustomDissolve", Float) = 0
		_DissolveFactor("DissolveFactor", Range( 0 , 1)) = 0
		_DissolveSoft("DissolveSoft", Range( 0 , 1)) = 0.1
		_DissolveWide("DissolveWide", Range( 0 , 1)) = 0.05
		_DissolveTexUSpeed("DissolveTexUSpeed", Float) = 0
		_DissolveTexVSpeed("DissolveTexVSpeed", Float) = 0
		_MainAlpha("MainAlpha", Range( 0 , 10)) = 1
		[Toggle(_FFNL_ON)] _FFnl("FFnl", Float) = 0
		[Toggle(_FDEPTH_ON)] _FDepth("FDepth", Float) = 0
		[HDR]_FnlColor("FnlColor", Color) = (1,1,1,1)
		_FnlScale("FnlScale", Range( 0 , 2)) = 0
		_FnlPower("FnlPower", Range( 1 , 10)) = 1
		[Toggle]_ReFnl("ReFnl", Float) = 0
		[Enum(Alpha,0,Add,1)]_BlendMode("BlendMode", Float) = 0
		_DepthFade("DepthFade", Range( 0 , 10)) = 1
		[HideInInspector] _texcoord2( "", 2D ) = "white" {}
		[HideInInspector] _texcoord( "", 2D ) = "white" {}
		[HideInInspector] __dirty( "", Int ) = 1
	}

	SubShader
	{
		Tags{ "RenderType" = "Transparent"  "Queue" = "Transparent+0" "IsEmissive" = "true"  }
		Cull [_CullMode]
		ZWrite Off
		ZTest LEqual
		Blend [_Scr] [_Dst], One OneMinusSrcAlpha
		
		CGPROGRAM
		#include "UnityShaderVariables.cginc"
		#include "UnityCG.cginc"
		#pragma target 3.0
		#pragma shader_feature_local _FDISSOLVETEX_ON
		#pragma shader_feature_local _FDISTORTTEX_ON
		#pragma shader_feature_local _FFNL_ON
		#pragma shader_feature_local _FMASKTEX_ON
		#pragma shader_feature_local _FDEPTH_ON
		#pragma surface surf Unlit keepalpha noshadow noambient novertexlights nolightmap  nodynlightmap nodirlightmap nofog nometa noforwardadd 
		#undef TRANSFORM_TEX
		#define TRANSFORM_TEX(tex,name) float4(tex.xy * name##_ST.xy + name##_ST.zw, tex.z, tex.w)
		struct Input
		{
			float4 vertexColor : COLOR;
			float2 uv_texcoord;
			float4 uv2_texcoord2;
			float3 worldPos;
			half3 worldNormal;
			float4 screenPos;
		};

		uniform half _Dst;
		uniform half _CullMode;
		uniform half _BlendMode;
		uniform half _Scr;
		uniform float4 _MainColor;
		uniform sampler2D _MainTex;
		uniform half _MainTexUSpeed;
		uniform half _MainTexVSpeed;
		uniform half _CustomMainTex;
		uniform float4 _MainTex_ST;
		uniform half _DistortMainTex;
		uniform half _DistortTexAR;
		uniform sampler2D _DistortTex;
		uniform half _DistortTexUSpeed;
		uniform half _DistortTexVSpeed;
		uniform float4 _DistortTex_ST;
		uniform half _DistortFactor;
		uniform float4 _DissolveColor;
		uniform half _CustomDissolve;
		uniform half _DissolveFactor;
		uniform half _DissolveWide;
		uniform half _DissolveSoft;
		uniform half _DissolveTexAR;
		uniform sampler2D _DissolveTex;
		uniform half _DissolveTexUSpeed;
		uniform half _DissolveTexVSpeed;
		uniform float4 _DissolveTex_ST;
		uniform half _DistortDissolveTex;
		uniform half _MainAlpha;
		uniform half _ReFnl;
		uniform half4 _FnlColor;
		uniform half _FnlScale;
		uniform half _FnlPower;
		uniform half _MainTexAR;
		uniform half _MaskTexAR;
		uniform sampler2D _MaskTex;
		uniform half _MaskTexUSpeed;
		uniform half _MaskTexVSpeed;
		uniform float4 _MaskTex_ST;
		uniform half _DistortMaskTex;
		UNITY_DECLARE_DEPTH_TEXTURE( _CameraDepthTexture );
		uniform float4 _CameraDepthTexture_TexelSize;
		uniform half _DepthFade;

		inline half4 LightingUnlit( SurfaceOutput s, half3 lightDir, half atten )
		{
			return half4 ( 0, 0, 0, s.Alpha );
		}

		void surf( Input i , inout SurfaceOutput o )
		{
			float Scr106 = _Scr;
			half2 appendResult4_g42 = (half2(_MainTexUSpeed , _MainTexVSpeed));
			float2 uv_MainTex = i.uv_texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
			half2 temp_output_3_0_g39 = uv_MainTex;
			half2 appendResult4_g33 = (half2(_DistortTexUSpeed , _DistortTexVSpeed));
			float2 uv_DistortTex = i.uv_texcoord * _DistortTex_ST.xy + _DistortTex_ST.zw;

			// jave.lin : 修复前
			//half2 panner5_g33 = ( 1.0 * _Time.y * appendResult4_g33 + uv_DistortTex);
			// jave.lin : 修复后
			half2 panner5_g33 = ( 1.0 * frac(_Time.y * appendResult4_g33) + uv_DistortTex);

			half4 tex2DNode7_g33 = tex2D( _DistortTex, panner5_g33 );
			half Distort148 = ( ( _DistortTexAR == 0.0 ? tex2DNode7_g33.a : tex2DNode7_g33.r ) * _DistortFactor );
			#ifdef _FDISTORTTEX_ON
				half2 staticSwitch316 = ( _DistortMainTex == 0.0 ? temp_output_3_0_g39 : ( temp_output_3_0_g39 + Distort148 ) );
			#else
				half2 staticSwitch316 = uv_MainTex;
			#endif
			half2 appendResult330 = (half2(i.uv2_texcoord2.x , i.uv2_texcoord2.y));
			// jave.lin : 修复前
			//half2 panner5_g42 = ( 1.0 * _Time.y * appendResult4_g42 + (( _CustomMainTex )?( ( staticSwitch316 + appendResult330 ) ):( staticSwitch316 )));
			// jave.lin : 修复后
			half2 panner5_g42 = ( 1.0 * frac(_Time.y * appendResult4_g42) + (( _CustomMainTex )?( ( staticSwitch316 + appendResult330 ) ):( staticSwitch316 )));
			half4 tex2DNode7_g42 = tex2D( _MainTex, panner5_g42 );
			half4 MainTexColor215 = ( _MainColor * tex2DNode7_g42 );
			half temp_output_275_0 = (-_DissolveWide + ((( _CustomDissolve )?( i.uv2_texcoord2.z ):( _DissolveFactor )) - 0.0) * (1.0 - -_DissolveWide) / (1.0 - 0.0));
			half temp_output_277_0 = ( _DissolveSoft + 0.0001 );
			half temp_output_272_0 = (-temp_output_277_0 + (( temp_output_275_0 + _DissolveWide ) - 0.0) * (1.0 - -temp_output_277_0) / (1.0 - 0.0));
			half2 appendResult4_g41 = (half2(_DissolveTexUSpeed , _DissolveTexVSpeed));
			float2 uv_DissolveTex = i.uv_texcoord * _DissolveTex_ST.xy + _DissolveTex_ST.zw;
			half2 temp_output_3_0_g40 = uv_DissolveTex;
			#ifdef _FDISTORTTEX_ON
				half2 staticSwitch314 = ( _DistortDissolveTex == 0.0 ? temp_output_3_0_g40 : ( temp_output_3_0_g40 + Distort148 ) );
			#else
				half2 staticSwitch314 = uv_DissolveTex;
			#endif
			// jave.lin : 修复前
			//half2 panner5_g41 = ( 1.0 * _Time.y * appendResult4_g41 + staticSwitch314);
			// jave.lin : 修复后
			half2 panner5_g41 = ( 1.0 * frac(_Time.y * appendResult4_g41) + staticSwitch314);
			half4 tex2DNode7_g41 = tex2D( _DissolveTex, panner5_g41 );
			half temp_output_308_20 = ( _DissolveTexAR == 0.0 ? tex2DNode7_g41.a : tex2DNode7_g41.r );
			half smoothstepResult264 = smoothstep( temp_output_272_0 , ( temp_output_272_0 + temp_output_277_0 ) , temp_output_308_20);
			half Alpha337 = _MainAlpha;
			half4 lerpResult223 = lerp( MainTexColor215 , _DissolveColor , ( _DissolveColor.a * ( 1.0 - smoothstepResult264 ) * Alpha337 ));
			#ifdef _FDISSOLVETEX_ON
				half4 staticSwitch298 = lerpResult223;
			#else
				half4 staticSwitch298 = MainTexColor215;
			#endif
			half4 temp_cast_0 = (0.0).xxxx;
			half Refnl339 = _ReFnl;
			float3 ase_worldPos = i.worldPos;
			half3 ase_worldViewDir = normalize( UnityWorldSpaceViewDir( ase_worldPos ) );
			half3 ase_worldNormal = i.worldNormal;
			half fresnelNdotV279 = dot( ase_worldNormal, ase_worldViewDir );
			half fresnelNode279 = ( 0.0 + _FnlScale * pow( 1.0 - fresnelNdotV279, _FnlPower ) );
			half temp_output_283_0 = saturate( fresnelNode279 );
			half4 FnlMainColor286 = ( _FnlColor * temp_output_283_0 * _FnlColor.a );
			half4 temp_cast_1 = (0.0).xxxx;
			#ifdef _FFNL_ON
				half4 staticSwitch300 = ( Refnl339 == 0.0 ? FnlMainColor286 : temp_cast_1 );
			#else
				half4 staticSwitch300 = temp_cast_0;
			#endif
			float4 MainColor98 = ( i.vertexColor * ( staticSwitch298 + staticSwitch300 ) );
			float MainTexAlpha138 = ( _MainColor.a * ( _MainTexAR == 0.0 ? tex2DNode7_g42.a : tex2DNode7_g42.r ) );
			half2 appendResult4_g44 = (half2(_MaskTexUSpeed , _MaskTexVSpeed));
			float2 uv_MaskTex = i.uv_texcoord * _MaskTex_ST.xy + _MaskTex_ST.zw;
			half2 temp_output_3_0_g43 = uv_MaskTex;
			#ifdef _FDISTORTTEX_ON
				half2 staticSwitch312 = ( _DistortMaskTex == 0.0 ? temp_output_3_0_g43 : ( temp_output_3_0_g43 + Distort148 ) );
			#else
				half2 staticSwitch312 = uv_MaskTex;
			#endif
			// jave.lin : 修复前
			//half2 panner5_g44 = ( 1.0 * _Time.y * appendResult4_g44 + staticSwitch312);
			// jave.lin : 修复后
			half2 panner5_g44 = ( 1.0 * frac(_Time.y * appendResult4_g44) + staticSwitch312);
			half4 tex2DNode7_g44 = tex2D( _MaskTex, panner5_g44 );
			#ifdef _FMASKTEX_ON
				half staticSwitch291 = ( _MaskTexAR == 0.0 ? tex2DNode7_g44.a : tex2DNode7_g44.r );
			#else
				half staticSwitch291 = 1.0;
			#endif
			half temp_output_270_0 = (-temp_output_277_0 + (temp_output_275_0 - 0.0) * (1.0 - -temp_output_277_0) / (1.0 - 0.0));
			half smoothstepResult256 = smoothstep( temp_output_270_0 , ( temp_output_270_0 + temp_output_277_0 ) , temp_output_308_20);
			half DissolveAlpha212 = smoothstepResult256;
			#ifdef _FDISSOLVETEX_ON
				half staticSwitch299 = DissolveAlpha212;
			#else
				half staticSwitch299 = 1.0;
			#endif
			half ReFnlAlpha318 = ( 1.0 - temp_output_283_0 );
			#ifdef _FFNL_ON
				half staticSwitch319 = ( Refnl339 == 0.0 ? 1.0 : ReFnlAlpha318 );
			#else
				half staticSwitch319 = 1.0;
			#endif
			float4 ase_screenPos = float4( i.screenPos.xyz , i.screenPos.w + 0.00000000001 );
			half4 ase_screenPosNorm = ase_screenPos / ase_screenPos.w;
			ase_screenPosNorm.z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? ase_screenPosNorm.z : ase_screenPosNorm.z * 0.5 + 0.5;
			float screenDepth348 = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, ase_screenPosNorm.xy ));
			half distanceDepth348 = abs( ( screenDepth348 - LinearEyeDepth( ase_screenPosNorm.z ) ) / ( _DepthFade ) );
			#ifdef _FDEPTH_ON
				half staticSwitch350 = saturate( distanceDepth348 );
			#else
				half staticSwitch350 = 1.0;
			#endif
			float MainAlpha97 = saturate( ( MainTexAlpha138 * staticSwitch291 * i.vertexColor.a * Alpha337 * staticSwitch299 * staticSwitch319 * staticSwitch350 ) );
			o.Emission = ( Scr106 == 5.0 ? MainColor98 : ( MainColor98 * MainAlpha97 ) ).rgb;
			half temp_output_100_0 = MainAlpha97;
			o.Alpha = temp_output_100_0;
		}

		ENDCG
	}
	CustomEditor "SampleGUI"
}

上面的 shader 代码中,搜索: “修复后”,机可查看到类似下面的代码:


...
			// jave.lin : 修复前
			//half2 panner5_g33 = ( 1.0 * _Time.y * appendResult4_g33 + uv_DistortTex);
			// jave.lin : 修复后
			half2 panner5_g33 = ( 1.0 * frac(_Time.y * appendResult4_g33) + uv_DistortTex);
...
			// jave.lin : 修复前
			//half2 panner5_g42 = ( 1.0 * _Time.y * appendResult4_g42 + (( _CustomMainTex )?( ( staticSwitch316 + appendResult330 ) ):( staticSwitch316 )));
			// jave.lin : 修复后
			half2 panner5_g42 = ( 1.0 * frac(_Time.y * appendResult4_g42) + (( _CustomMainTex )?( ( staticSwitch316 + appendResult330 ) ):( staticSwitch316 )));
...
			// jave.lin : 修复前
			//half2 panner5_g41 = ( 1.0 * _Time.y * appendResult4_g41 + staticSwitch314);
			// jave.lin : 修复后
			half2 panner5_g41 = ( 1.0 * frac(_Time.y * appendResult4_g41) + staticSwitch314);
...
			// jave.lin : 修复前
			//half2 panner5_g44 = ( 1.0 * _Time.y * appendResult4_g44 + staticSwitch312);
			// jave.lin : 修复后
			half2 panner5_g44 = ( 1.0 * frac(_Time.y * appendResult4_g44) + staticSwitch312);
...

这种优化方式也有局限性的,因为我们的 sampler 的 filer mode 是 repeat,所以 uv 值域可以控制再 -1 ~ 1 即可,因为可以使用 frac 来优化,也可以 fmod(val, 1.0) 但是这个过于费,因为使用 frac 就OK

这个问题的是100%必现的,最终发布到出问题的手机上验证,修复了


其实这个解决方法,我以前在学习 B站上的 庄懂 TA巨佬 就有分享过
现在想起帮助还是挺大的


Project

backup : Testing_Effect_Error_4_RenderDoc_UV精度不足、断层的修复.rar文章来源地址https://www.toymoban.com/news/detail-500537.html

到了这里,关于Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录--前端金额运算精度丢失问题及解决方案

    前端开发中难免会遇到价格和金额计算的需求,这类需求所要计算的数值大多数情况下是要求精确到小数点后的多少位。但是因为JS语言本身的缺陷,在处理浮点数的运算时会出现一些奇怪的问题,导致计算不精确。 本文尝试从现象入手,分析造成这一问题原因,并总结和整

    2024年02月19日
    浏览(44)
  • EasyCVR播放设备录像出现部分视频不能播放的原因排查与解决

    EasyCVR视频融合平台基于云边端协同架构,具有强大的数据接入、处理及分发能力。平台支持多协议接入,包括:国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等,对外可分发多格式视频流,包括RTSP、RTMP、FLV、HLS、WebRTC等。 有用户反馈,通过SDK接入的设备,

    2024年02月12日
    浏览(44)
  • Unity - 记一次非正规变体优化带来的兼容性导致部分手机卡死的问题

    在 2023.4.6 我们的 角色展示界面 就遇到了 华为手机,red mi note 11 的测试手机上的 后 2023.5.24 再次遇到类似的问题,但是这次重现的地方很多,不单止 角色展示界面 遇到 排除过: 模型 特效 场景 人物 材质 后来多次排查,发现是 PBR 所有的 变体拆分优化 的文件导致阴影部分

    2024年02月08日
    浏览(46)
  • 忽视BYOD(自带设备)安全:员工自带设备的安全策略缺失或不足

    随着企业越来越依赖 BYOD 政策来提高工作效率和灵活性,员工自带的设备成为组织网络安全的重要组成部分。然而,许多组织对 BYOD 安全政策的管理不到位、缺乏足够的风险意识及实施措施不完善等问题导致 BYOD 风险不断上升,对企业信息资产构成威胁。本文将深入探讨 BY

    2024年02月02日
    浏览(42)
  • 解决:HBuilderX运行到手机提示没有检测到设备

    1、背景: 最近在开发app的时候,用hbuilderx运行到手机提示检测不到设备,通过以下步骤进行解决 2、操作: 我的手机是小米9的,首先保证手机是属于开发者USB调试模式 具体步骤: ①进入设置界面,点击【我的设备】 ②进入设备后有个【MIUI版本】,连续点击【MIUI版本】进

    2024年02月11日
    浏览(67)
  • 记录Selenium Python访问浏览器时部分内容无法获取的解决方法

    部分内容无法显示: 出现这种情况可能是浏览器对爬虫进行拦截,可以为webdriver添加浏览器设置。 添加浏览器设置后成功显示文本内容: 完整测试代码:

    2024年02月07日
    浏览(48)
  • 【已解决】华为手机短接后有提示音但在其他设备里显示未知设备或者USB-SER怎么办 | 华为荣耀手机短接后未知设备里面出现“USB-SER” 端口如何解决

    电脑提前打开 设备管理器 ,短接插线后注意观察电脑反应,如果成功的话电脑会有设备连接提示音并在设备管理器里刷新出华为麒麟深刷端口( HUAWEI USB COM 1.0 (COM3) )。如果电脑没任何反应,你应该检查短接工具,数据线,电脑插口,手机是否关机状态,然后多短接几次试

    2024年02月13日
    浏览(120)
  • UniApp已经接了手机数据线,但运行工具警告 “没有检查到设备“ (华为手机为例 进行解决)

    大部分第一次使用uni进行手机调试都会遇到这个问题 首先 将手机的数据线插入电脑的usb接口是必备前提 然后 就是手机的权限拦截了设备扫描 这就是uni工具找不到设备的原因 接入手机线后 数据会弹出一个USB的提示 点进去之后 我们要设置 允许传输文件 千万别仅充电 接下来

    2024年02月09日
    浏览(76)
  • 解决Unity打包后Timeline里部分特效没显示的bug

    比较诡异的问题,美术同学给过来的特效资源,在Edtior里是正常播放的,但打包后特效里应该落下来的光柱却消失了。 考虑到打包后的环境和Editor环境的区别 AssetBundle 通过在Editor里加载AssetBundle来播放,发现也是正常的,应该不是资源问题。 ParticleSystem的Culling Mode 粒子系统

    2023年04月08日
    浏览(40)
  • 手机录像内存不足变为tmp格式修复为MP4步骤

    用手机录像1个多小时后,手机提示内存不足,APP出错,导致视频变成TMP格式,没有正常保存为MP4,TMP并不是常见的视频格式,这通常是因为文件未成功写入而处于临时状态。尝试使用各种播放器打开这个文件,但无一例外,都无法正常播放。想修复正常播放,而且是音画同步

    2024年03月13日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包