共计 5810 个字符,预计需要花费 15 分钟才能阅读完成。
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(原群已满员)