UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - texture
type: channel
link: https://blog.uwa4d.com/tag/texture
items: 开发微信小程序游戏，有没有类似Debug真机图形的方法
items: Screen.SetResolution和URP的RenderScale有什么区别
items: 从Gamma空间改为Linear空间会导致性能下降吗
items: 非2的幂次的ASTC纹理格式尺寸对带宽的影响
items: SRP Batcher在真机上失效
items: 纹理开启Mipmap导致压缩失败的问题
items: 在Runtime下，IL2CPP与Mono打包对应的PSS内存占用问题
items: UWA问答精选
items: Android平台压缩纹理ETC2 VS ASTC
items: 使用Streaming Mipmap后纹理内存没有下降的疑问

开发微信小程序游戏，有没有类似Debug真机图形的方法
type: item
date: 2025-01-03T07:29:00+02:00
description: 1）开发微信小程序游戏，有没有类似Debug真机图形的方法 2）Unity中如何实现动态实时的车削效果 3）动态创建的Texture，有什么办法可以让他保持ASTC么 4）Unity转微信小游戏的日志问题 这是第416篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：793972859 Rendering Q：开发微信小程序游戏有什么科学的Debug真机图形的方法吗？比如RenderDoc？ 针对以上问题，有经验的朋友欢迎转至社区交流： https://answer.uwa4d.com/question/677250003d306f3e9d594de3 Rendering Q：请问这种车削的效果怎么实现？ A1：动态生成顶点和索引，比较省事的做法是事先生成很密的圆柱型网格，动态修改下顶点位置。 感谢jump晃悠@UWA问答社区提供了回答 A2：轴向半径尺寸图类似高度图，记录一维度上的R值即可，算很小的量。 感谢偶尔不帅@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/67724d2b3d306f3e9d594de0 Texture Q：动态创建的Texture，有什么办法可以让他保持ASTC么？ 创建是传的纹理格式不起作用么？ _gifTexture = new Texture2D(1, 1, TextureFormat.ASTC_6x6, false); 传了格式，然后加载出来就给转成ARGB32了。 按理说他这API里有格式参数，应该能用才对，不对的话那就是Bug。而且真机测试也是支持ASTC的。 public Texture2D(int width, int height, TextureFormat textureFormat, bool mipChain) :this(width, height, textureFormat, mipChain ?Texture.GenerateAllMips:1,false,IntPtr.Zero,false,false,(string)null) { } A1：自己压缩，CPU或者GPU。你再看看你的设备是否支持你创建的这个格式： SystemInfo.SupportsTextureFormat。 感谢小波@UWA问答社区提供了回答 A2：压缩ASTC极慢，Unity不可能给你动态压缩，要自己转换格式，自己保存文件。可以找找载入Raw纹理的方法，动态载入DDS格式就是用Raw。不是RawImage，是Texture2D.LoadRawTextureData。 感谢jump晃悠@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/67724eb63d306f3e9d594de1 WebGL Q：Unity转微信小游戏有没有类似Bugly之类的日志上报功能？如果要自己做日志上报，是不是要开Full With Stacktrace选项才可以？ 针对以上问题，有经验的朋友欢迎转至社区交流： https://answer.uwa4d.com/question/67724f6b3d306f3e9d594de2 封面图来源于网络 今天的分享就到这里。生有涯而知无涯，在漫漫的开发周期中，我们遇到的问题只是冰山一角，UWA社区愿伴你同行，一起探索分享。欢迎更多的开发者加入UWA社区。 UWA官网：www.uwa4d.com UWA社区：community.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859

Screen.SetResolution和URP的RenderScale有什么区别
type: item
date: 2023-12-27T03:30:00+02:00
description: 1）Screen.SetResolution和URP的RenderScale有什么区别 2）相同压缩格式相同面积不同数量资源加载速度 3）新增Tag再生成AssetBundle并热更新之后，代码获取到的是undefined 这是第367篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 Rendering Q：请问Screen.SetResolution和UniversalRenderPipelineAsset.renderScale有什么区别？ 之前低端机都是通过Screen.SetResolution降低渲染分辨率提高性能，发现UniversalRenderPipelineAsset有一个renderScale也可以降低渲染效果。想请问下，两者本质区别是什么？在低端机两者一起降会更好？ A1：参考URP文档： https://docs.unity3d.com/cn/Packages/com.unity.render-pipelines.universal@12.1/manual/universalrp-asset.html RenderScale的调整影响的是ColorAttachment的分辨率，SetResolution影响的是BackBuffer的分辨率，两个一起用会变成相乘的效果。文档里说不影响UI渲染分辨率特指的是Overlay UI，用相机渲染的UI还是会受到RenderScale影响的。 感谢宗卉轩@UWA问答社区提供了回答 A2：RenderScale是针对相机的，这也是URP要做场景分辨率分离的原因。 感谢ZJS@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/657bbfff40a8d93b624afc25 Texture Q：比如1张ASTC的1024*1024和4张512*512，哪种方式加载速度更快，性能最优？ 先说下我的理解：更小的内存意味着内存寻址更快，Miss的更少，而且内存也是分页的，页数更少，同时在GPU的读取过程中，带宽的加载速度以及缓存都会更优一些。 但是我这仍然需要一定的更深的理论或者更权威的证明。 以及是否不同压缩格式，结论可能相反呢？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/6576d6b740a8d93b624afc24 AssetBundle Q：新增Tag名称是：test1， 生成AssetBundle之后进行热更新。 在代码里获取对节点设置的Tag得到的是undefined，我看我新增的test1的Tag是存储在Prefab里面的，为什么生成AssetBundle热更新之后就获取不到了，是不是Unity的Tag是跟随底包一起打进去的。 疑问：是不是读取节点的Tag时会判断这个Tag是不是在底包里Unity的相关设置里是否存在，存在就正确获取到，否则返回undefined，那能不能在不更新APK的情况下，新增一个Tag并热更新下去正常使用获取呢？ A：Tag不能热更，延伸出去就是ProjectSettings下的东西基本都不能热更。所以建议Tag可以在整包更新的时候预留多一些，为后面热更做准备。 感谢junbin.liu@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/658102e340a8d93b624afc64 封面图来源于网络 今天的分享就到这里。生有涯而知无涯，在漫漫的开发周期中，我们遇到的问题只是冰山一角，UWA社区愿伴你同行，一起探索分享。欢迎更多的开发者加入UWA社区。 UWA官网：www.uwa4d.com UWA社区：community.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：465082844

从Gamma空间改为Linear空间会导致性能下降吗
type: item
date: 2023-08-22T05:31:00+03:00
description: 1）从Gamma空间改为Linear空间会导致性能下降吗 2）如何处理没有使用Unity Ads却收到了GooglePlay平台的警告 3）C#端如何处理xLua在执行DoString时候死循环 4）Texture2DArray相关 这是第350篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 Rendering Q：Linear性能比Gamma差吗？我们项目从之前使用的是Unity 2020.2.7f1版本，选择的是Gamma。目前升级到2021.3.21f1，切换为Linear空间，Shader和图片都进行过修改，性能也优化过。 但是总体测试下来性能不如之前的Gamma，帧率没有以前高，帧率掉了很多，经过优化，还是不太令人满意，总感觉会卡顿，不知道是不是从Gamma升级到Linear的原因？ A1：应该和换颜色空间没关系。如果没有特殊功能，Gamma和Linear的主要区别就是最后输出到显示器时要不要做颜色的修正，根据你的描述应该和修改Shader有关。 感谢李伟@UWA问答社区提供了回答 A2：在硬件支持的设备上，不应当有明显的性能差异。 在硬件不支持的情况下（比如OpenGL ES 2.0），如果是基于Shader中的模拟转换来实现Linear Space的效果，会有一定的GPU消耗。但是如果感受上是卡顿，而非持续的低帧率，那也不像是这种情况，建议从具体的性能Profile数据入手来进行排查。 这里有一个相关的讨论，搜索performance关键词可以看到一些人做的实验： https://forum.unity.com/threads/gamma-vs-linear-space.613294/ 部分结论引用如下： “I have just done a stress test of Gamma vs Linear color spaces with transparencies and Gamma is indeed a liiiitle faster than Linear, but the difference is so minimal it doesn't even matter. (2 to 3 frames per second more on a stress test that was overdrawing 8 transparent planes one over the other for the full screen space.) On any GPU that handles GLES3 there is no performance reason to use Gamma space over Linear. Gamma space is legacy now and is only useful for legacy GLES2 GPUs (because linear requires GLES3)” 不同的游戏测试结果可能略有差异，但原理上应该是没有可观测的性能差异的，题主可以参考一下。 感谢贾伟昊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/64d2fe8066b5c657c78be152 Script Q：我没有使用Unity Ads，但仍然收到了GooglePlay平台的警告： 您的“xxxxxxx”应用（版本代码：8）包含“com.unity3d.ads:unity-ads”SDK 或您的某个代码库所依赖的SDK，该SDK会收集个人数据或敏感数据，这些数据包括但可能不仅限于Advertising ID，Android ID标识符。根据用户数据政策的相关规定，应用不得将永久性设备标识符与其他个人数据、敏感的用户数据或可重置的设备标识符相关联。 自世界协调时间（UTC）2023年1月11日午夜起，如果新应用版本包含SDK版本且不符合用户数据政策，则可能无法发布。您可以考虑将该SDK升级至不含违规代码的合规版SDK（若有），或者从您的应用内移除该SDK。 根据您的SDK提供方的情况，您可以考虑升级到4.0.1，并/或联系您的SDK提供方，看看是否有合适的更高版本可用。Google无法推荐任何第三方软件，也无法为这类软件提供任何背书。 A1：建议检查下SystemInfo的引用。 感谢Knight-132872@UWA问答社区提供了回答 A2：提供几个思路： 1、确认Package下有没有com.unity.ads包 2、如果使用的是Unity…

非2的幂次的ASTC纹理格式尺寸对带宽的影响
type: item
date: 2023-08-08T04:47:00+03:00
description: 1）非2的幂次的ASTC纹理格式尺寸对带宽的影响 2）​C#端如何处理xLua在执行DoString时候死循环 3）如何制定美术规范或者各个模块的指标 4）如何处理Lua的io.open出现中文路径 这是第348篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 Texture Q：有一张UI纹理尺寸1200x554，纹理格式ASTC 4x4，显示占用内存0.6MB，将MaxSize改为1024，占用内存476KB。 除了内存的降低外，想请问下对带宽或其他性能的影响大么？ 纹理类型是Default，Advanced -> Non-Power of 2 -> ToNearest/... 选项，但是UI没有，UI是否也有必要自己实现ToNearest？ A：题主可以参考一下知乎的这个回答： https://www.zhihu.com/question/376921536 也可以参考： https://gamedev.stackexchange.com/questions/26187/why-are-textures-always-square-powers-of-two-what-if-they-arent 简单来说有如下几个信息： GPU的寻址是按块进行的，ASTC纹理的压缩也是按照块进行压缩的，因此贴图尺寸最好符合这个设定； 不满足的贴图通过补充额外空间来满足对应的需求，这里会有部分的空间浪费。 具体到题主的问题： 将MaxSize设置为1024，其实是减少了贴图尺寸，内存/显存占用变少是肯定的； 贴图尺寸降低，肯定是会减少带宽消耗，也有可能提升显存的采样命中率，包括加载方面因为文件大小变小都会有提升，但这些“好处”未必那么好量化，比较明显的应该是带宽降低。 UI的贴图通常会做合图的操作，因此很多UI自身是不需要做尺寸上的要求的，但是如果不合图的话，整体上还是建议按照power of 2的尺寸在做设计，这种规范比较简洁清晰，容易执行。 感谢贾伟昊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/64c9bb260b33622d467d7c85 Script Q：我使用xLua作为游戏的内嵌脚本语言，允许玩家自定义脚本。 现在有个玩家在脚本里面写了一个死循环，当我用DoString去加载这个脚本时候会直接卡死，于是我在外面加入了一个Task： var isSucceed = false; var task = Task.Run(() => { isSucceed = sandbox.DoString(xxxx)//这里简化一下.核心就是加载这个脚本执行DoString }); bool isCompletedSuccessfully = task.Wait(TimeSpan.FromMilliseconds(1500)); //1.5s timeout if (!isCompletedSuccessfully) { CELog.LogError("加载脚本超时"); isSucceed = false; luaEnv.Dispose(); //Kill掉当前的Evn return; //不再加载后续脚本 } 现在是只要调用‘luaEnv.Dispose()’编辑器就直接闪退，无论是这里Timeout了调用，还是等几秒以后。 我感觉是因为Task的Timeout只是在超时后回调，但是此时Lua还在死锁中，所以我无法Dispose。 官方的FAQ提了一句： 调用LuaEnv.Dispose崩溃。 很可能是这个Dispose操作是由Lua那驱动执行，相当于在Lua执行的过程中把Lua虚拟机给释放了，改为只由C#执行即可。 感觉和我这个情况是一样的，这种情况我应该怎么处理? A：在外部结束Lua虚拟机肯定是有很大崩溃风险的，我觉得有两个思路供参考： 建立一个完整的沙盒环境，类似Dock，这个环境内运行逻辑，外部可以把这个环境销毁掉，不会对外部造成任何影响，这个在Unity下可能难度比较大，要做逻辑和表现的分离，然后构建一个纯逻辑层的运行环境。 在Lua虚拟机内部监测死循环的情况，然后自主中断，抛出Error。这个是我们现在在用的方式，改造Lua虚拟机，监测一定时间内一直在执行某些字节码超过一定阈值就认为自己是在死循环把自己结束掉。当然还有一些别的条件，比如栈深度检测等等。这种自主中断并且抛错的方式其实更加完美。具体实现可以参考这个文章的思路： https://ld246.com/article/15221…

SRP Batcher在真机上失效
type: item
date: 2023-05-16T05:38:00+03:00
description: 1）SRP Batcher在真机上失效 ​2）Shader里面对同一张纹理多次采样会影响效率吗 3）为什么纹理开启了mipmap后，纹理内存反而下降了 4）TMP为什么有多次Delegate.Combine()的GC 这是第336篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 Rendering Q：Shader是Compatible的，在编辑器里面DrawCall也是SRP Batcher合批的，但是在真机上却没有合批成功，是什么原因造成的？ A：需要排查对应的Shader是否存在在Constant Buffer中却不在Properties中的Uniform变量，这种状况会导致在OpenGLES的真机上SRP Batcher失效，但是这种状况在编辑器里面是SRP Batcher合批且Shader显示是Compatible的。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6461dca1742de67bf974f2d9 Shader Q：Shader里面对同一张纹理做多次采样会影响效率吗？ float2 flowVector = tex2D(FlowMap, IN.uvMainTex).rg * 2 - 1; float noise = tex2D(FlowMap, IN.uvMainTex).a; 如上代码，有资料简单提了一句说Shader代码编译的时候会自动优化到一次采样里面去，不过并没提是SurfaceShader才有的编译优化还是所有的Shader的编译优化都会这样？ A：测试结果来看，只要是uv相同的贴图采样，surface和unlit shader编译之后都会优化掉多余的采样次数。 感谢范世青@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/645b523cb068ba13373fb56e Texture Q：为什么纹理开启了mipmap后，纹理内存反而下降了？ A：很可能是Quality Settings里面的Texture Quality选择的不是Full Res导致的，比如选择的是Half Res，这样对于开启了mipmap的纹理来说，第0层的mipmap层级就不会加载进内存，所以纹理内存反而表小了。 经过测试，1024x1024 ETC2_8Bits格式的纹理，没开启mipmap是1MB，开启了变成333KB，512x512 ETC2_8Bits格式的纹理，开启mipmap前后分别是256KB和128KB。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6461dace742de67bf974f2d8 Lua Q：只有一个界面对一个TMP的OnPreRenderText进行了一次+=的操作，为什么在其他界面也发现有Delegate.Combine()的GC，且每次大小不同？ 这是唯一操作过的界面： 这是其他界面，有2M的，还有些几十K的。 A：Unity TextMeshPro (TMP) 组件的OnPreRenderText事件是一个委托类型，可以通过 += 运算符来订阅事件，但每次订阅事件时都会创建一个新的委托实例。如果需要多次订阅事件，需要使用Delegate.Combine() 方法将多个委托实例合并为一个。但是，每次使用Delegate.Combine() 方法都会创建一个新的委托实例，这可能会导致频繁的垃圾回收。 根据你的描述，只有一个界面对一个TMP的OnPreRenderText 进行了一次 += 的操作，但在其他界面也发现了Delegate.Combine() 的垃圾回收。这可能是由于 TMP 组件在内部订阅了OnPreRenderText事件，并且每次订阅事件时都会使用Delegate.Combine() 方法。此外，可能还存在其他脚本或组件订阅了该事件，导致创建了额外的委托实例。 每次Delegate.Combine() 方法创建的委托实例的大小可能不同，这取决于合并的委托实例的数量和每个委托实例的大小。因此，每次Delegate.Combine() 方法调用时，垃圾回收器可能会回收不同大小的垃圾。为了减少垃圾回收的频率和影响，你可以尽可能减少使用 Delegate.Combine() 方法的次数，并确保及时取消订阅不再需要的事件。 感谢轩辕小羽@UWA问答社区提供了回答，欢迎大…

纹理开启Mipmap导致压缩失败的问题
type: item
date: 2023-02-21T07:57:00+02:00
description: 1）纹理开启Mipmap导致压缩失败的问题 ​2）使用TextMeshPro能否避免使用Resources文件夹 3）用透视摄像机去分层管理UI的优势和好处 4）Houdini中切线空间向量怎么在Unity Shader还原出原向量 这是第325篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：answer.uwa4d.com UWA QQ群：465082844 Texture Q：看到一些优化建议中说，ASTC压缩格式在开启Mipmap之后需要保证纹理尺寸为2的幂次方。 可是Mipmap的生成不受纹理尺寸的影响（非2的幂次方会有性能开销，但也可以生成Mipmap），ASTC压缩也是不受尺寸大小限制的。 但为什么非2的幂次方纹理开启Mipmap采用ASTC压缩格式会压缩失败？中间是有什么冲突吗？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/63ef3af206385405990c2e7b TextMeshPro Q：使用TextMeshPro时，自带有Resources文件夹里面会放字体资源和TMP_setting，最后打测试包发现占据的内存还是比较大，而且我只用了一个字体。 有无办法不使用Resources？或者减少Resource内存大小呢？ 参考：https://blog.csdn.net/akof1314/article/details/87985603 A：如果你对修改源码没有意见，建议修改源码。 把所有Resource.Load调用，代理成自定义方法（大概3处左右）。 感谢1 9 7 3-311135@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/63f0798606385405990d43e6 UI Q：用透视摄像机去分层管理UI，是有什么优势和好处吗？能联想到的就是透视摄像机可以调节大小、位置、旋转、方便做3D效果，还是说还有一些别的优势？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/63ecba39063854059909f1e8 Rendering Q：目前有一个需求， 在Houdini中，将法线从模型空间转换到切线空间后，保存到顶点颜色中，在Unity Shader通过读取顶点颜色将法线从切线空间转换到模型空间。 Houdini中：生成切线选择MikkT算法，和Unity保持一致： vector T = normalize(v@tangentu); vector B = normalize(v@tangentv) ; vector N = normalize(@N); matrix m = set(@T, @B, @N); @Cd = m * @Cd; @Cd = @Cd * {-0.5，0.5，0.5} + 0.5; //Houdini是右手坐标系，加负号转左手坐标系 在Unity Shader中： float3 bitangent = cross(normalize(v.normal) , normalize(v.tangent.xyz)) * v.tangent.w; float3x3 TtoO = float3x3(v.tangent.x, bitangent.x, v.normal.x, v.tangent.y, bitangent.y, v.normal.y, v.tangent.z, bitangent.z, v.normal.z); float3 normalOS = v.color.xyz; normalOS = normalOS * 2 -1; normalOS = mul(TtoO, normalOS) ; 但是这样转换出的法线是不对的。 然后做了如下测试：在Houdini中，直接将法线写入顶点颜色通道： @Cd = @N; @Cd = @Cd * 0.5 + 0.5; @Cd = normalize(@Cd); @N = @Cd; Unity中，通过RenderDoc截帧： 向法线和顶点写入同样的数值，Unity中得到的向量顺序不一样，数值可能小数也有偏差。 哪位大佬有Unity源码的代码能不能看下Unity在导入FBX时做了哪些计算，怎么能构建出Houdini中的TBN逆矩阵来还原出houdini写入的切线空间向量？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/63ed923206385405990a…

在Runtime下，IL2CPP与Mono打包对应的PSS内存占用问题
type: item
date: 2023-01-31T03:42:00+02:00
description: 1）在Runtime下，IL2CPP与Mono打包对应的PSS内存占用问题 ​2）获得AssetBundle内部依赖关系的方法 3）Unity 2019 Streaming Mipmap在某些情况下采样等级错误 4）根据RenderDoc的数据，计算渲染量 这是第322篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：answer.uwa4d.com UWA QQ群：465082844 Memory Q：IL2CPP打包比Mono打包在Runtime下跑同样的案例PSS内存占用更高一些，请问是合理的吗？ A：推测可能是IL2CPP包是64位的，而Mono包是32位的，天然内存占用就会高一些，另外IL2CPP在打包的时候，会把各种泛型的代码给展开，所以对应的代码so加载进内存，内存占用也会高一些。 下面是同样的测试案例，两种打包方式的PSS占用截图。 Mono包： IL2CPP包： 从上图中可以看到，IL2CPP包比Mono包内存占用更多的体现在Code、Native Heap和Private Other三个类别上。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/63d774d60638540599f6bdb8 AssetBundle Q：获得AssetBundle内部依赖关系的方法。注：Manifest的依赖关系不准确。 之前发现从Manifest里面获得的依赖关系在很多情况下都不准确。 比较明显的是，当Prefab嵌套时，Manifest数据会显示Prefab依赖被嵌套的Prefab；而SpriteAtlas和Sprite依赖关系是反的。其他还有很多情况会额外依赖不需要的资源。用WebExtract解开AssetBundle本身，里面的数据是正确的依赖数据。 因此，现在想找到一个方法，脱离Manifest，自行建立依赖关系表。 现在的问题在于，如果对每个输出的AssetBundle执行解包和正则分析，会花费大量时间，并且本身文本匹配也有风险。 有没有什么干净的流程，可以获得AssetBundle内部记录的依赖关系？ A：用UnityEditor.Build.Content.ContentBuildInterface下面的方法获取到的依赖信息是准确的。如下面两个函数： ContentBuildInterface.GetPlayerDependenciesForObjects ContentBuildInterface.CalculatePlayerDependenciesForScene 如果用SBP，Manifest可以在编译完成后加个Task读m_DependencyData，自己建立一个。或者直接用ContentBuildInterface预构造的也可以满足了。 感谢题主欧月松@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/632a6dfae73cb53fa4d725bc Texture Q：游戏使用了Mipmap技术，同时为了节省内存开启了流式加载Streaming Mipmap： 但是在做热更模型的时候，发现某些贴图的Mipmap会采样一个很低的值（很糊），然后即便调整摄像机远近也没有变化（不能动态采样了）。 正常打包出来的资源没有问题（贴图在一个独立Bundle里），但热更打出了的资源就有问题（模型、材质、贴图等都在一个Bundle里），而且贴图占用内存未达到Budget上限。 不知道问题出在哪了，该如何解决？ A：根据描述分析，有可能是加载了贴图之后把Bundle卸载了。把贴图放在单独的Bundle里面的时候，可能这个Bundle没有被卸载；但在热更的时候，贴图和模型、材质等放在同一个Bundle，可能用代码加载这个Bundle之后又卸载了，就会出现这个问题。 Streaming系统刚开始加载的时候会加载分辨率较低的一层Mipmap，之后根据距离动态调整，如果此时已经把贴图所在的Bundle卸载了，就无法根据摄像机距离调整采样的Mipmap层级。 感谢龙粲@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/63c78cba0638540599e9a17a Rendering Q：最近在分析几款游戏的特效。已经用RenderDoc抓了几帧。也找到了渲染粒子特效的Pass。 现在问题，能否从顶点Buffer中分析出粒子的数量？或者有无别的方法估算出粒子的数量？ A：如下图，如果是四边形的粒子，比如bill…

UWA问答精选
type: item
date: 2022-07-05T08:37:00+03:00
description: 1）Unity性能优化分析思路 ​2）资源打包关系依赖树 3）SpriteAtlas 中Include in Build的作用 4）使用Streaming Mipmap后纹理内存没有下降的疑问 5）URP Renderer Feature实现二次元描边，Cutout的处理问题 UWA每周推送的知识型栏目《厚积薄发 | 技术分享》已经伴随大家走过了330个工作周。精选了2022年上半年的精彩问答分享给大家，期待UWA问答继续有您的陪伴。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Unity Q：Unity有多少优化点？比如合批：静态合批、SRP合批、GPU实例化、UGUI Reruild、光照烘焙、反射探针、光照探针、Shader.Parse、Shader.CreateGPUProgram、场景加载优化和GC优化，还有哪些优化点？ A1：大方向上可以从CPU、内存、GPU这三个方向切入。 细分一下可以从CPU、内存、渲染、资源优化、耗电优化、网络优化、卡顿优化、优化工具的选择掌握这几个点入手。 一、CPU优化 缓存计算结果 预处理 限帧法 主次法 多线程 引擎模块（动画、物理、粒子、导航） 逻辑优化 二、内存优化 缓存法 内存池 资源管理器 控制GC 逻辑优化 Shader变体数量优化 三、渲染优化 SetPassCall渲染状态切换频次控制 DrawCall数量控制 带宽负载 显存占用 GPU计算量 四、卡顿优化 降帧法 摊帧法 限制数量法 逻辑优化 IO优化 使用进度条 五、资源优化 纹理优化 UI优化 字体优化 模型优化 场景优化 粒子优化 材质优化 指定标准美术规范 Shader变体数量优化 六、耗电优化 上面说到的优化点，或多或少都会影响到手机的耗电，也是优化耗电的措施，除此之外还有： 动态调整限帧 动态调整画质 七、网络优化 减少无用字段 降低字段精度 避免重复发送 网络异步化 压缩无效字节 压缩协议包 以上说的这些要点，大部分摘抄归纳自《移动游戏性能优化通用技法》。强烈建议多花些时间认真阅读一下这篇文章，然后以这篇文章作为指南，再去仔细研究里面提到的优化细节该如何展开。 感谢马三小伙儿@UWA问答社区提供了回答 A2：优化点肯定是无穷无尽的，这里搬运UWA的客户端性能优化思路，针对常见的引擎模块的相关问题都做了分析，讲的是比较全比较透的，常见的优化难题都罗列了。 《Unity性能优化 — 物理模块》 《Unity性能优化 — 动画模块》 《Unity性能优化系列 — 资源内存泄漏》 《Unity性能优化系列—Lua代码优化》 《粒子系统优化——如何优化你的技能特效》 《Unity性能优化系列—加载与资源管理》 《Unity性能优化系列—渲染模块》 《Unity性能优化 — UI模块》 《支持资源加载分析、场景分割》 《UWA报告使用小技巧，你get了吗？》 《UWA本地资源检测更新，助你严守项目性能的每个角落！》 感谢芭妮妮@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/61a0a56ed8413e18eb297ac3 AssetBundle Q：想做包体资源分析，大家有什么好的树显示工具或者思路推荐吗？有比较好的开源方案也可以。最简单就像N叉树一样，比如root一个文件名，然后展开整个树结构。 A1：我自己做了一个，供参考。都是用Unity自己的IMGUI最基本的接口去实现。 EditorWindows GUI.Box GUI.BeginGroup GUI.Label Handles.DrawBezier Handles.DrawWireDisc TreeView 基本上，组织好各个AssetBundle的依赖关系其实是很好呈现的。 感谢黄程@UWA问答社区提供了回答 A2：推荐一款比较好用的插件，不止有依赖树，还有其他打包的资源数据可供分析： https://assetstore.unity.com/packages/tools/utilities/build-report-tool-8162 感谢郑骁@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/623c8322a43e6117d040ae9b AssetBundle Q：SpriteAtlas中Include in Build的作用是什么？ A：专门做了一些测试，具体如下： 以下表达中Sprite对应的是Sprite类型的对象，Texture2D对应的是Texture2D的对象，这和Sprite对象是完全不同的东西，sactx表示生成的图集纹理。 测试情…

Android平台压缩纹理ETC2 VS ASTC
type: item
date: 2022-06-14T04:07:00+03:00
description: 1）Android平台压缩纹理ETC2 VS ASTC ​2）Unity使用Profiler和UWA内存差异巨大 3）Unity 2020 IL2CPP打包异常 4）TouchScreenKeyboardWrap在PC模式下打包报错 这是第301篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Texture Q：1.2022年在Android平台的ASTC支持度怎么样了，预计2023年上的游戏能不能上ASTC？ 1.1 跟iOS统一方便处理 1.2 更多选择控制压缩比例 44->1212 1.3 效果比ETC2更好 1.4 ASTC有没有什么坑，看到有说华为部分机器不支持，会黑屏 网上只找到下面这个数据，2020年9月，ASTC 77%。 https://developer.android.google.cn/guide/app-bundle/asset-delivery/texture-compression?hl=zh-cn 2.我理解的压缩纹理是CPU不用解压，直接传输给GPU，直接GPU硬件采样。相对于采样ARGB32格式，采样压缩纹理的消耗是不是更高点，还是可以忽略不计？ 3.移动平台纹理是否是2份？CPU一份，GPU显存一份，还是共享同一份？ 4.ASTC/ETC2的压缩纹理尺寸是否需要2的幂？网上有些说法是非2的幂纹理加载到显存的时候会进行转换成2的幂，转换过程耗时，会导致卡顿。 https://blog.csdn.net/linxinfa/article/details/108827197 我做过以下测试： 1.AssetBundle内的纹理尺寸是原始尺寸。 2.Mumu模拟器+GPA纹理尺寸是原始尺寸，格式转换成了ARGB32。 3.Adreno+高通真机，目前还在测试，找的机器连不上Adreno Profiler。 A1：我2017年立项的时候跟你一样处理过这个问题，我当时的策略是主包使用ASTC，启动更新的时候判断玩家是否支持ETC2，不支持的话下载ETC2版本的AssetBundle资源。资源在线上是完全独立的2份资源（打包的时候每次打包2份独立资源）。当年是为了海外做的这个兼容。经过这几年各个大厂的洗礼，直接ASTC就行了。如果你们的游戏类型一定要下探到那么老的机器，就像我那种双保险的做法。 1.黑屏的问题没遇到。ETC2反而因为压缩算法不好，部分颜色失真，导致你在做部分PBR效果的时候，会有问题。 2.需要硬件支持，就是因为不能用CPU去处理这种软解压跟软压缩，可以忽略。 3.移动平台GPU跟CPU是共享一个内存，但是GPU会独立开辟一份内存，所以会有2份。开启了Mipmap的情况下不是单纯的2份相同内存，所以还有Texture Streaming这种方式来减少贴图内存占用。 4.ASTC不需要。 至于你的测试： Mumu模拟器在《楚留香》出来的时候就支持ASTC，后面吃鸡游戏风靡的时候更是所有模拟器都支持了，不支持的都要被淘汰。这块可以不用考虑。如果不是单独为了发行模拟器渠道，大部分情况下，发行公司都是要求禁用模拟器登录的。 感谢简单就好@UWA问答社区提供了回答 A2：1.关于ASTC的支持度，题主查的数据本身可以作为参考，但还需要结合考虑项目发行的市场。比如实际上对于中国市场而言ASTC的覆盖率已经非常高，而对于东南亚南美等海外市场则还要酌情； 2.常见的压缩纹理是直接降低纹理资源质量，以质量换性能的行为，它不会在GPU端重新解压缩，相反在内存、带宽等方面都有所优化； 3.只有当纹理资源需要运行时修改、开启了Read/Write Enable选项时，才会向CPU复制一份，否则就只有GPU的一份； 4.ASTC对分辨率没有需求；ETC2要求分辨率为4的倍数，而非2的次幂；特别地，不论是ASTC还是ETC2，如果开启了Mipmap，则必须是2的次幂，否则同样会压缩失败。 感谢Faust@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/62a15f62b87a45735173440e Memory Q：Unity使用Profiler和UWA内存差异为何差别这么大？ A：Profiler显示的是引擎真实的分配内存，但这个内存在OS中并不仅仅是这些，它会分配更多的内存Page，而且不同的OS版本，不同的厂商分配的都不一样。 同时，OS层还会启动很多自身的Lib，比如渲染相关的库、文件加载的加速库等等，这些内存的分配，都是Unity统计不到的。 除此之外，还有虚…

使用Streaming Mipmap后纹理内存没有下降的疑问
type: item
date: 2022-05-31T04:07:00+03:00
description: 1）使用Streaming Mipmap后纹理内存没有下降的疑问 ​2）TCP网络传输大端/小端疑问 3）Texture Compression，Default和Override有什么关系 4）如何快速清除Log 这是第299篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Texture Q：为什么我在项目中使用了Streaming Mipmap但是在GOT报告中看纹理内存没有下降？是没有正确生效还是统计有问题？ A：之前做过相关测试，发现GOT Online是可以统计到被Streaming Mipmap影响的纹理的正确内存的，所以我推测你遇到的情况大概率还是没有正确生效导致的。以下是对如何让一张纹理应用Streaming Mipmap的简单流程总结，其中会注明需要特别注意的一些条件（有些被官方文档收录，有些则文档中没有，但实验证明为必要）： 在Project Settings-Quality中开启Texture Streaming选项。然而实验发现Editor中开启该选项而真机上却会失效的现象，导致所有纹理的Streaming Mipmap设置全部失效。所以为了确保生效，首先应该在代码中调用QualitySettings.streamingMipmapsActive API全局地开启这个选项，才能确保Streaming Mipmap可用。 调整1中设置的参数。比较重要的参数是Memory Budget参数和Max Level Reduction参数。Memory Budget表示纹理资源的预算，默认值是512MB，但根据UWA的大量项目数据来看，中低端机上一般为200MB左右。它的数值代表的是所有纹理资源的预算——即，它既包括了非流式的纹理、又包括了我们想要采用流式的纹理——但这个“预算”并不代表纹理资源可占用的上限，只是Unity判断对于一个开启Streaming Mipmap的纹理到底采用它的哪些Mipmap通道的参考值，非流式纹理能够轻易突破这个预算。 Max Level Reduction则是代表着Unity通过流式存储最高能取到哪一级的Mipmap通道，这个参数的优先级比Memory Budget要高，也就会造成实际内存超过预算的情况。（比如该参数为2时，则最多剔除Mipmap0和1通道，即便丢弃以后还远超出预算值也不会进一步剔除。） 也就是说，如果Memory Budget值设置的远高于项目中纹理实际占用的内存，则Texture Streaming可能完全不起效，所有开启Streaming Mipmap的纹理仍将保留它们的全部Mipmap通道。 设置开启Streaming Mipmap的纹理。1、2中提到的设置只对开启了Streaming Mipmap的纹理起效，而这只是官方文档的说法，从实际操作来看，Texture Streaming只对同时满足以下三个条件的纹理生效： 1）开启了Streaming Mipmap且开启了Generate Mipmap的纹理（这一点官方文档中没有提及，事实上开启Generate Mipmap才会生成Mipmap通道供Streaming Mipmap剔除）； 2）被即时加载的纹理（如一开始就已经在场景中被依赖的纹理，即便开启了Streaming Mipmap其内存也不会发生变化，通过AssetBundle加载和Res.Load()加载的纹理则可以），也即官方文档中这句话的实际含义： 如果是进行Android开发，还需要打开Build Setting，并将Compression Method设置为LZ4或LZ4HC。Unity需要使用其中一种压缩方法进行异步纹理加载，这是纹理串流系统所必需的操作。 3）Gfx部分内存（这里指的是纹理资源开启Read/Write选项时，复制到CPU端的那一部分内存是不受Streaming Mipmap影响的）； Streaming Mipmap剔除Mipmap通道的规律。它的机制其实和Texture Quality是类似的。我们知道，开启Mipmap的纹理之所以会变成原来的4/3倍，实际上是它各个通道所占用的内存之和。举例而言，一个具有11个Mipmap通道的原大小为1MB的纹理（10241024分辨率、ASTC44格式），其内存占用为1+1/4+1/16+…的11项等比数列之和，即约4/3。等比数列的各项就对应了Mipmap0、Mipmap1、Mipmap2…等各个Mipmap通道。那么，当Max Level Reduction参数设置为2时，其实际意义就是保留Mipmap2…