1)GPU Skinning旋转指定骨骼
2)对于UGUI画布重建以及动静拆散
3)如何设定游戏内存的峰值来保障不闪退
4)应用UsePass遇到Keyword失落的问题
5)Unity Shader Built-in外面宏的定义


这是第237篇UWA技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫10分钟,认真读完必有播种。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

Rendering

Q:应用GPU Skinning的物体,相似头须要面对角色,如何旋转指定骨骼呢?当初的想法是传入一个Matrix和骨骼编号,Shader里再解决,然而算进去都是0点地位。反编译了同样实现的我的项目,传入的是个骨骼地位float3和骨骼旋转float4的变量(看命名是这个意思)。

A:实现思路就是在骨骼矩阵计算时将LookAt的旋转利用到Neck Bone及其Child Bone上(若骨骼矩阵计算也是在Shader中实现的,而不是离线预计算好的,则不思考Child Bone)。

不晓得题主的GPU Skinning是如何实现的,以chengkehan/GPU Skinning的开源库为例做了个简略的测试。

将小球的旋转矩阵传入Shader:

采样预计算骨骼矩阵时将旋转利用到Neck骨骼以下(boneindex > 21)所有骨骼节点计算(PS:子骨骼节点的计算是有问题的,因为矩阵没有交换律,请自行处理。)

成果如下图:

感激羽飞@UWA问答社区提供了答复

UGUI

Q:对于UGUI画布重建以及动静拆散,教训证UI元素的大小地位变动并不会引起画布网格重建的问题?

看到很多UWA答复说UI元素的大小地位变动会引起重构,然而通过UGUI钻研发现并不会。UGUI引起重绘元素汇合是CanvasUpdateRegistry类中的,如下图:

通过反射将网格重绘列表打印进去之后发现地位、大小和旋转都不会进入重建列表,而Anchors、Pivot还有组件的Color和宽高扭转才会引起网格重构,请问怎么回事?

A1:能够看看OnRectTransformDimensionsChange函数、VertexHelper类的代码、地位和Rect大小等,这些的扭转都会SetDirty的。

VertexHelper里的几个List,其实是对应的材质属性和顶点地位属性;按理说这些扭转都是会Setdirty的,然而从RectTransform的一些属性来看,Unity可能只在Pivot、SizeDelta、AnchorMin和AnchorMax这四个属性更改时才会Setdirty。

感激李星@UWA问答社区提供了答复

A2:能够依照李星的说法做个验证,写一个MyImage继承自Image,而后Override外面的OnRectTransformDimensionsChange,如下图:

在场景中应用MyImage,就能够验证更改Anchor的地位或者Rect的宽高会触发OnRectTransformDimensionsChange(这个音讯是从Native层发回来的),触发这个是会触发SetVerticesDirty的。批改Position和Scale这些是不会触发SetVerticesDirty的,批改色彩是会触发SetMaterialDirty。这两种SetDirty都会将对应的元素退出到GraphicRebuildQueue外面,最终的耗时都会统计到Canvas.SendWillRenderCanvases外面。这部分的“重构”并不是指网格重构,这个“重构”能够了解为UI元素自身的更新。

另外一种网格重构,是指UI变动导致了Canvas重建,就是会在Native层进行网格拼合,也就是会触发调用Canvas.BuildBatch。能够参考:
https://answer.uwa4d.com/question/59af579c6a071c595e8994b2#59af5d466a071c595e8994b4

感激Xuan@UWA问答社区提供了答复

A3:网格重建(Canvas.BuildBatch)是在Native层做的,用Rider看不到外面内容。批改Position会触发重建,是Unity官网文档里明确写进去的。

这是我之前对各种文章做的一些总结《UGUI优化 - 知识点》,能够参考:
https://www.jianshu.com/p/5c44eb589751

感激Walker@UWA问答社区提供了答复

Memory

Q:不同内存的安卓与苹果机型上(1G、2G、3G、4G…),游戏内存的峰值个别最高多少能保障不闪退?

A1:这里有人会继续更新iOS上的内存峰值,帖子上面还有人发了一个测试峰值的工具:
https://stackoverflow.com/questions/5887248/ios-app-maximum-memory-budget

感激dra@UWA问答社区提供了答复

A2:做一个搬运工,感激Jasper的测试数据提供,我将其放到这里,不便大家间接查看:

device: (crash amount/total amount/percentage of total)
iPad1: 127MB/256MB/49%
iPad2: 275MB/512MB/53%
iPad3: 645MB/1024MB/62%
iPad4: 585MB/1024MB/57% (iOS 8.1)
iPad Mini 1st Generation: 297MB/512MB/58%
iPad Mini retina: 696MB/1024MB/68% (iOS 7.1)
iPad Air: 697MB/1024MB/68%
iPad Air 2: 1383MB/2048MB/68% (iOS 10.2.1)
iPad Pro 9.7": 1395MB/1971MB/71% (iOS 10.0.2 (14A456))
iPad Pro 10.5”: 3057/4000/76% (iOS 11 beta4)
iPad Pro 12.9” (2015): 3058/3999/76% (iOS 11.2.1)
iPad Pro 12.9” (2017): 3057/3974/77% (iOS 11 beta4)
iPad Pro 11.0” (2018): 2858/3769/76% (iOS 12.1)
iPad Pro 12.9” (2018, 1TB): 4598/5650/81% (iOS 12.1)
iPad 10.2: 1844/2998/62% (iOS 13.2.3)
iPod touch 4th gen: 130MB/256MB/51% (iOS 6.1.1)
iPod touch 5th gen: 286MB/512MB/56% (iOS 7.0)
iPhone4: 325MB/512MB/63%
iPhone4s: 286MB/512MB/56%
iPhone5: 645MB/1024MB/62%
iPhone5s: 646MB/1024MB/63%
iPhone6: 645MB/1024MB/62% (iOS 8.x)
iPhone6+: 645MB/1024MB/62% (iOS 8.x)
iPhone6s: 1396MB/2048MB/68% (iOS 9.2)
iPhone6s+: 1392MB/2048MB/68% (iOS 10.2.1)
iPhoneSE: 1395MB/2048MB/69% (iOS 9.3)
iPhone7: 1395/2048MB/68% (iOS 10.2)
iPhone7+: 2040MB/3072MB/66% (iOS 10.2.1)
iPhone8: 1364/1990MB/70% (iOS 12.1)
iPhone X: 1392/2785/50% (iOS 11.2.1)
iPhone XS: 2040/3754/54% (iOS 12.1)
iPhone XS Max: 2039/3735/55% (iOS 12.1)
iPhone XR: 1792/2813/63% (iOS 12.1)
iPhone 11: 2068/3844/54% (iOS 13.1.3)
iPhone 11 Pro Max: 2067/3740/55% (iOS 13.2.3)

同时,Slyv也对上述测试数据做了一个更为宏观的总结,具体如下:
device RAM: percent range to crash
256MB: 49% - 51%
512MB: 53% - 63%
1024MB: 57% - 68%
2048MB: 68% - 69%
3072MB: 63% - 66%
4096MB: 77%
6144MB: 81%

Special cases:
iPhone X (3072MB): 50%
iPhone XS/XS Max (4096MB): 55%
iPhone XR (3072MB): 63%
iPhone 11/11 Pro Max (4096MB): 54% - 55%

该问答由UWA提供

Shader

Q:为了共用Shader代码,把若干个Pass写在一个独自的Shader A中,在Shader B中用UsePass关键字组合成不同的SubShader。

在PC上没什么问题,然而打包AssetBundle当前发现外面的Keyword失落。咱们是通过ShaderVariantCollection收集的变体,并且确定ShaderVariantCollection含有须要的Keyword,如果不必UsePass间接写代码,Keyword没有失落。

请问是否不能通过这种办法来共用含有Keyword的Shader代码?

A1:猜想楼主应用AssetBundle的办法过程中,没有先加载共用的Shader A,只加载了Shader B和SVC,所以导致Shader解析的时候缺失了共用Shader A的Pass信息,而PC上没问题是因为所有的Shader资源都在。

感激李星@UWA问答社区提供了答复

A2:我在这个网址(https://forum.unity.com/threads/keywords-and-usepass.324180/)上看到了相似你的问题,他们答复说是UsePass前面跟的Pass名字必须是大写。

感激安日天@UWA问答社区提供了答复

A3:须要解析进去援用的Shader,并依据变体列表剖析出援用Shader的变体列表,增加到SVC外面。

感激承影@UWA问答社区提供了答复

A4:测试后(打包成exe测试)发现,把SVC文件和Shader打包在一个AssetBundle外面,应用UsePass也不会呈现Keyword失落的问题的。如果SVC和Shader离开打包,就算不应用UsePass也会呈现Keyword失落的问题。

感激Xuan@UWA问答社区提供了答复

Shader

Q:Unity Shader外面的UNITY_FAST_COHERENT_DYNAMIC_BRANCHING宏,示意什么意思?什么时候这个宏是true?

A:在HLSLSupport.cginc中有定义:

#if (SHADER_TARGET < 30) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES) || defined(SHADER_API_N3DS)    //no fast coherent dynamic branching on these hardware#else    #define UNITY_FAST_COHERENT_DYNAMIC_BRANCHING 1#endif 

比方上面这段代码,这些条件判断也决定是否应用UNITY_BRANCH来跳过if为false外面的代码:

half UnityDeferredSampleRealtimeShadow(half fade, float3 vec, float2 uv){    half shadowAttenuation = 1.0f;    #if defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE)        #if defined(SHADOWS_SCREEN)            shadowAttenuation = tex2D(_ShadowMapTexture, uv).r;        #endif    #endif    ++**#if defined(UNITY_FAST_COHERENT_DYNAMIC_BRANCHING) && defined(SHADOWS_SOFT) && !defined(LIGHTMAP_SHADOW_MIXING)    //avoid expensive shadows fetches in the distance where coherency will be good    UNITY_BRANCH    if (fade < (1.0f - 1e-2f))    {    #endif**++        #if defined(SPOT)            #if defined(SHADOWS_DEPTH)                float4 shadowCoord = mul(unity_WorldToShadow[0], float4(vec, 1));                shadowAttenuation = UnitySampleShadowmap(shadowCoord);            #endif        #endif        #if defined (POINT) || defined (POINT_COOKIE)            #if defined(SHADOWS_CUBE)                shadowAttenuation = UnitySampleShadowmap(vec);            #endif        #endif    #if defined(UNITY_FAST_COHERENT_DYNAMIC_BRANCHING) && defined(SHADOWS_SOFT) && !defined(LIGHTMAP_SHADOW_MIXING)    }    #endif    return shadowAttenuation;} 

感激李星@UWA问答社区提供了答复


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在UWA问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官网技术QQ群:793972859(原群已满员)