在小米10安卓12系统上闪退,同样的手机在安卓11系统和安卓12.5系统上就不闪退,原因是自己拓展的效果在CBuffer里没有字节对齐。
闪退错误 :ApiGLES::ClearBufferSubData(unsigned int, gl::BufferTarget, long, long)+168)
如下图所示,必须要按half4 half2 half 从上到下的顺序写,顺序不能乱不能穿插的写,不然就会闪退,还有不能写half3,要用half4代替half3,不然在某些机器上会显示错误。
Shader Graph也同时存在同样问题引起闪退,如下图所示,它是按照属性定义的顺序排列,并不会字节对齐。
找到Shader Graph的代码PropertyCollector.cs
public void GetPropertiesDeclaration(ShaderStringBuilder builder, GenerationMode mode, ConcretePrecision inheritedPrecision)
在最上面进行排序。
| 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 |         public void GetPropertiesDeclaration(ShaderStringBuilder builder, GenerationMode mode, ConcretePrecision inheritedPrecision)         {             //字节对齐排序             properties.Sort((a1, a2) => {                 string value1 = a1.concreteShaderValueType.ToShaderString(a1.concretePrecision.ToShaderString());                 string value2 = a2.concreteShaderValueType.ToShaderString(a2.concretePrecision.ToShaderString());                 string last1 = value1.Length > 0 ? value1.Substring(value1.Length - 1, 1) : "";                 string last2 = value2.Length > 0 ? value2.Substring(value2.Length - 1, 1) : "";                 int order1 = int.MinValue;                 int order2 = int.MinValue;                 if (!int.TryParse(last1, out order1))                 {                     if (value1 == "float")                         order1 = -1;                     else if (value1 == "half")                         order1 = -2;                 }                 if (!int.TryParse(last2, out order2))                 {                     if (value2 == "float")                         order2 = -1;                     else if (value2 == "half")                         order2 = -2;                 }                 return -order1.CompareTo(order2);             }); | 
改完后终于字节对齐了。小米12安卓10系统不再闪退
在检查一下CBUFFER_START里包的属性没有在Properties中声明,如果没有声明也会闪退。
| 1 2 3 4 5 6 7 8 9 | Shader "Universal Render Pipeline/Lit" {     Properties     {         //CUBFFER_SART 里包的属性必须要在这里声明, 不然会闪退!!     } } | 
在检查一下采样器是否超过16个,SAMPLER(sampler_XXX)这里只是采样器的声明,只有调用SAMPLE_TEXTURE2D才会真的采样。如果Texture本身就是空,这里还是会占采样器的数量。
| 1 2 3 4 5 6 7 8 9 10 | TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); half4 frag(Varyings IN) : SV_Target {     half4 c = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);     return c; } | 
如果明确贴图没有使用,最好包一层宏,这样可以减少采样寄存器。
| 1 2 3 4 5 6 7 | #if defined(A_ON)     return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); #else     return 1; #endif | 
最后在检查一下CBUFFER_START里属性的数量,尽可能的减少数量,太多了也会在小米10上闪退。
- 本文固定链接: https://www.xuanyusong.com/archives/4932
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
                        	捐  赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
                        
                        					







urpbug挺多的,最新的unity6,在urp管线下,选择vulken安卓平台,在shadergraph连一个输出uv0作为颜色给一个cube,在编辑器下显示正常但是导出到我的小米13上uv就好像丢失了一样。
涨知识了
DrawBuffersBatchMode 和 WriteLineVertex 这两个闪退 大佬知道什么原因么
vulkan 会有这样的情况吗? 小米10 应该是可以用vulkan的把?
目前来看vulkan还是支持的不够好,大部分都还用的opengles3
对齐的时候float4和half4这样的都算一种吗?还是float类型的先排完然后到half类型呢?
float4放在前面
这种问题更好奇是如何定位的,一句字节对齐,这里面不知道要多少汗水
一点点试验 连蒙带猜
啊?这玩意儿官方没有任何说明吗
我记得官方声明中只说了要拼成4的倍数?这么离谱吗
我也是一点点测试出来的。 – -!