1)URP下与Built-in的Light Color不一致
2)开启MSAA的RenderTarget会对没开启MSAA的RenderTarget造成影响
3)角色Mesh合并的优点与缺点
4)NGUI渲染层级的原理
5)Unity上App图标安装到设备上图标模糊,设置上的注意点
这是第234篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
Rendering
Q:发现Light的Intensity在不为1的情况下,光照的颜色在URP下滑Built-in管线下不一致。附件里有2个工程,使用Unity 2019.4.11f1,分别是URP和Built-in管线的(都是线性空间)。(附件可戳原问答下载)
再现方法:
1. 打开2边工程的Scene1,这个场景的方向光Intensity值设置为1。观察2个工程里球的光照颜色,是一致的,通过FrameDebugger也可以确认这一点。
2. 打开2边工程的Scene2,这个场景的方向光Intensity值设置为0.65。观察2个工程里球的光照颜色,Built-in管线的更暗,通过FrameDebugger也可以看到Built-in管线的工程光照颜色数值小一点。
URP颜色:
Built-in颜色:
URP FrameDebugger:
Built-in FrameDebugger:
A:用楼主Demo里面的Light的颜色做了一下计算,在Light设置项里面,Light Color为(0,202,255),202.0/255 = 0.792。
SRP:
Green通道:
Mathf.GammaToLinearSpace(0.792) * 0.65=0.5906189 * 0.65= 0.383902285Blue通道:
Mathf.GammaToLinearSpace(1) * 0.65=1 * 0.65=0.65Built-in:
Green通道:
Mathf.GammaToLinearSpace(0.792*0.65)=0.2280943Blue通道:
Mathf.GammaToLinearSpace(0.65)=0.3800563应该是下面两段数值的计算区别:
GammaToLinearSpace(m_ColorFilter * m_Intensity);
GammaToLinearSpace(m_ColorFilter) * m_Intensity;查询发现是由于GraphicsSettings.lightsUseLinearIntensity这个数值不一样导致的。在SRP里面这个数值是True,在Built-in里面是False。
感谢Xuan@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fed681710a17c6c2b09d7db
Rendering
Q:在同一帧中,我有用于渲染的RenderTarget开启了MSAA,和用于热扭曲效果的扭曲Buff,是一张没有开启MSAA的RenderTarget,在后处理中这张扭曲Buff会用来偏移UV,以实现扭曲效果。在PC上和iOS上一切正常,但是在Android真机上出现异常。在高通GPU上,这张扭曲Buff会导致屏幕出现网格状的现象,在Mali GPU上会出现各种细碎的小黑方块,应该是一个未知原因导致扭曲Buff上的数据被处理成我不期望的状态。
如果我把其他的RenderTarget的MSAA关闭,这种现象就会消失,也就说开启MSAA的RenderTarget会对没开启MSAA的RenderTarget造成影响,且仅仅是在Android真机上出现,不同的GPU表现还不一样。有遇到类似问题的吗?求解。
A:该问题已经解决了。我所遇到的问题的最终情况,不是开启MSAA的RenderTarget会对没开启MSAA的RenderTarget造成影响。在开启MSAA后,主相机的RenderTexture(MSAA)绑定到Shader上,会有类似如下操作:
texture(_Main_Tex, UV + Offset)
不知道是Unity的Bug还是其他原因,导致在Android真机上,绑定到Shader上的RenderTexture一定不是经过有效ResolveAA的版本,所以在如上操作的时候就出现异常表现,类似细碎方块或者网格等等现象,如果Offset是0,不会有异常表现,这些应该和Mobile GPU上的TBR有关系。
那么我需要在Android真机上传入一张经过有效ResolveAA的RenderTexture即可。经过验证,使用如下方式可以解决:
RenderTexture.Blit(Rt_msaa, Rt_no_msaa);
这样我就得到一张经过有效ResolveAA的Rt。
感谢题主yangkang@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5ff28a3f10a17c6c2b09d80d
Rendering
Q:为了让身体各部件合并,所有部件都要开启Readable/Writable属性,合并也创建新的Mesh来合并,多个部件合并成一个Mesh有什么好处吗?
游戏类型是MMOARPG,比如可以换头发、脸、衣服等,资源量很大,如果不合并,走挂点的方式与合并成一个Mesh会怎么样呢?
A:第一个问题的好处应该就是方便合批,坏处除了你说的几点,还有贴图的合并,这些点都会造成内存的额外开销。是否应用还是应该看具体的项目类型。
第二个问题其实就是内存换Draw Call,看你们项目这两块哪一部分是瓶颈了。另外还需要注意材质,如果各部位材质差别很大也是无法合批的。
感谢范君@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fe0064510a17c6c2b09d6fe
NGUI
Q:Unity Shader判断层级关系的唯一标准是否是深度测试?我看NGUI的Shader并没有ZTest配置并且关闭了深度写入,那应该是根据渲染的先后顺序来控制层级?也就是说sortOrder sortLayerName renderQ camera depth都只是Unity在控制不同组件进入渲染流水线的顺序吗?
A:深度测试在传统的渲染管线里,是发生在Fragment Shader之后(不考虑Early Z等优化技术),用来剔除那些被遮挡的像素。本身和Draw Call提交的顺序没有关系。
Unity引擎中,有很多参数能决定渲染顺序,也就是Draw Call提交顺序。
首先最高优先级的是Camera,引擎中的渲染是由Camera发起的,在Built-in管线中,主要依靠Camera的Depth来决定哪个Camera看到的物体先渲染。最常见的结构,比如Depth=0的相机画场景,另一个Depth=1的相机画UI。但是,现在URP里的相机的Camera Stack也是类似的结构,用来控制Camera的渲染先后顺序。
然后是RenderQueue,这个用来决定物体的渲染顺序。例如,内置的Opaque和Transparent等等,具体可以看Unity的文档,这个值就是越小的物体越先画。同一个RenderQueue里,不同类型的物体渲染顺序也是有一定规则。比如,引擎默认的排序规则下Opaque的物体一般是从前往后渲染,而Transparent的物体为了保证渲染的正确性,是需要从后往前渲染的。
SortingLayer和OrderInLayer之类的主要用在UGUI Canvas上,能影响UI的渲染顺序。
另外,问题中有提到UI的Shader中没有配置ZTest,关闭ZWrite,这也是正常的,具体开什么关什么,是要根据渲染的物体的类型决定的。因为UI排序一般由UI系统内部的一些参数决定,是和深度无关的。常规的一些透明物体也是会关闭ZWrite,只保留ZTest的。
感谢范君@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fed6be210a17c6c2b09d7de
Editor
Q:Unity上App图标安装到设备上图标模糊,设置上有什么特别注意的吗?
A1:请题主查下Unity的Import Settings,这个是对打在包里的图标文件也有作用的,可以将这些图标的Import Settings中的压缩去掉。
感谢芭妮妮@UWA问答社区提供了回答
A2:补充一下,也需要注意本身图标的设置。我们因为是导出工程,所以使用的图标资源其实是跟安卓版本一致有多个分辨率版本。
感谢ZeaLotSean@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5ff5225910a17c6c2b09d8f6
图片来源于网络
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)