共计 3320 个字符,预计需要花费 9 分钟才能阅读完成。
1)如何给带通明的 Sprite 生成深度图
2)SpriteAtlas 中 Include in Build 的作用
3)multi_compile 的 Keyword 是不是须要被动退出到 SVC 外面去
4)Shader 里 4 个 float 和 float4 的差异
这是第 282 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。
UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)
Rendering
Q:如下图:场景是用 Sprite 拼的,需要是应用 ShadowMap 给精灵增加实时暗影,做法是用一个摄像机对精灵进行拍摄以渲染 Depth 数据到 Render Texture 上生成 ShadowMap,而后在地板 Shader 里对 ShadowMap 进行采样绘制出暗影。
教程链接:https://blog.csdn.net/l364244…
当初遇到的问题是:
拍摄精灵时 Shader 的 RenderType 只能是 Opaque,不能应用 Transparent 和 TransparentCutout,导致的问题是半透明边缘无奈失常投影,请帮忙看一下如何解决。
上图中,两头的胶囊失常暗影,左侧为投影成果(疏忽渲染不失常),右侧为原图,右下角是生成的 ShadowMap。
A:能够参考一下这个教程:https://catlikecoding.com/uni…
感激羽飞 @UWA 问答社区提供了答复
AssetBundle
Q:SpriteAtlas 中 Include in Build 的作用是什么?
A:专门做了一些测试,具体如下:
以下表白中 Sprite 对应的是 Sprite 类型的对象,Texture2D 对应的是 Texture2D 的对象,这和 Sprite 对象是齐全不同的货色,sactx 示意生成的图集纹理。
测试状况包含 2 个变量:
- SpriteAtlas 对象是否被动打包 AssetBundle
- SpriteAtlas 对象上是否勾选 Include in Build
第一种状况,SpriteAtlas 打包 AssetBundle:
那这里要思考的是 SpriteAtlas 援用的 Sprite 是否会独自打包,如果这些小 Sprite 不被动打包,是会被动进这个 SpriteAtlas 的 AssetBundle 外面的,如果其余的 UI Prefab 中,比方有个 Image 应用了一个小 Sprite,那么这个小 Sprite 就冗余了。
这里勾不勾选 Include in Build 的区别在于:加载 Image 的时候,这个 Image 会不会主动显示,勾选了 Include in Build,会主动显示图片,不勾选,则须要脚本增加回调来被动加载 SpriteAtlas,并 callback(spriteatlas)。
第二种状况,SpriteAtlas 不退出 AssetBundle 打包:
- 不勾选 Include in Build
假如小的 Sprite 打包 AssetBundle,在这个 AssetBundle 外面不会有 sactx,这个 sactx 的 Texture2D 的纹理变成“隐没”的状态,没有任何货色能够援用到这个 sactx 纹理,而且因为在工程外面有 SpriteAtlas 的存在,所以在小的 Sprite 的 AssetBundle 外面也不能让其自身对应的小的 Texture2D 纹理进 AssetBundle 包,所以图像就永远显示不进去了。勾选 Include in Build
所有的小的 Sprite 所在的 AssetBundle 外面都会被动蕴含 sactx 的图,且会蕴含所有没有被动打包的小的 Sprite。如 Sprite1 和 Sprite2 是 SpriteAtlas 外面的两个小的 Sprite。Sprite1 被动打包,Sprite2 不被动打包,那么 Sprite1 的 AssetBundle 外面是会有 Sprite1 和 Sprite2 以及 sactx 纹理。
总结:
- 如果有 Sprite 退出了某个 SpriteAtlas,那么任何真正应用到这个 Sprite 的资源都不会有对 Sprite 对应的小的 Texture2D 纹理的援用,而是对 sactx 图集纹理的援用。
- 如果 SpriteAtlas 不打包,必须勾选 Include in Build,否则 sactx 纹理就“隐没”了,在勾选 Include in Build 的前提下,而且 SpriteAtlas 中的所有小的 sprite 必须打包到同一个 AssetBundle 外面,否则 sactx 会冗余。
- 如果 SpriteAtlas 打包了 AssetBundle,sactx 永远不会冗余了(这里的冗余是指打包 AssetBundle 造成的冗余)。SpriteAtlas 外面的小的 Sprite 也最好打包 AssetBundle,不然这些小的 Sprite 就会冗余。勾选或者不勾选 Include in Build 都不影响各种依赖关系,惟一的区别是是否会被动显示图片,勾选了就会被动显示图片,不勾选就须要脚本管制来显示图片。
感激 Xuan@UWA 问答社区提供了答复
AssetBundle
Q:multi_compile 是不是须要被动退出到 SVC 外面去?
A:对于一个 Shader 资源来说,在我的项目进行打包构建时,multi_compile 定义的关键字会把 Shader 中含有该关键字但理论未应用的变体也进行构建,而 shader_feature 定义的关键字则不会。
但当咱们我的项目中应用 SVC 收集变体时,并不是所有 multi_compile 定义的变体都须要被动退出到 SVC 中,只有咱们理论用到的须要收集。
进行试验如下:
试验构建场景,通过 SVC 收集变体、打成 AssetBundle 包。在场景中提前加载并 Warmup,再实例化一个用到相干 Shader 中变体“FOG_EXP2”的预制体。(变体“FOG_EXP2”是 multi_compile 关键字定义的。)状况一:SVC 中没有蕴含变体“FOG_EXP2”。此时会在实例化时触发 Shader.CreateGPUProgram(相当于回到该 SVC 所援用的 Shader 中去加载了),不满足咱们收集变体并预热、从而升高游戏过程中 Shader 加载耗时的需要。
状况二:SVC 中收集了变体“FOG_EXP2”。实例化时没有触发 Shader.CreateGPUProgram,阐明该变体被失常 Warmup 了。
论断是,对于包体构建是没有区别的,SVC 打包时会依赖对应的 Shader,multi_compile 定义的关键字天然都会参加构建;对于变体预热,只有是须要用到的变体,必须收集到 SVC 中并 Warmup 后,才不会在实例化渲染时触发 Shader.CreateGPUProgram。
感激 Faust@UWA 问答社区提供了答复
Rendering
Q:明天看 URP 代码,发现 URP 里会把一些原本是 float 的数据平铺到 4 个 float 中,再用一些 Mask 之类的操作取出数据。
用 float4 与用 4 个 float 的区别是什么?看起来是有一些性能上的差异之类,URP 里才会这样用。
A1:Float4 能够利用 SIMD 指令减速。
感激时雨苍炎 @UWA 问答社区提供了答复
A2:ES3.0 的 vertex shader 中的 attribute,float 会依照 float4 进行计算。
感激 Tsai@UWA 问答社区提供了答复
A3:应该是 CBuffer 的内存对齐 float4 更好组织数据,不容易呈现 Bug。
HLSL CBuffer Packing 规定能够参考:
https://docs.microsoft.com/en…
感激羽飞 @UWA 问答社区提供了答复
封面图来源于网络
明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)