关于_CameraDepthTexture的疑惑

1)关于_CameraDepthTexture的疑惑
​2)贴图Alpha通道对图片大小的影响
3)URP要怎么实现GrabPass的效果
4)如何获取AssetDatabase加载失败的Asset的Instance ID
5)如何判断Bundle文件加载进内存的时机html


这是第226篇UWA技术知识分享的推送。今天咱们继续为你们精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。git

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

Rendering

Q:一个关于_CameraDepthTexture的疑问。缓存

若是开启_CameraDepthTexture,Camera就须要渲染一遍场景内全部带有ShadowCaster的可见物体的Pass来实现深度图。网络

可是场景中的物体在开启ZWrite的时候就把深度写进了Depth Buffer中了,直接得到这个Depth Buffer是否是比近乎DrawCall翻倍的方式更有效率呢?仍是Unity在这方面有什么考虑?编辑器

另外,问一个更实际的问题:
咱们的项目须要渲染场景的中湖水的深度效果,全部不透明的场景物体的材质都是关联一样一个Shader,这个Shader是带有ShadowCaster的。可是只有个别插入水中的物体须要去渲染ShadowCaster的Pass,有没有方法在不增长Shader的状况下,让没有插入水里的物体不渲染Shadow Caster Pass呢?咱们用的是Built-in的渲染管线。ide

A:第一个问题,能够参考这个问题中Unity官方人员的回复。
里面讲了两个缘由,第一是对于非全屏渲染的状况,原本是想拿对应相机渲染的深度,可是Depth Buffer是全屏的。第二个缘由是由于不少平台不支持直接拿Depth Buffer的数据。

参考网页:
https://forum.unity.com/threads/poor-performance-of-updatedepthtexture-why-is-it-even-needed.197455/函数

另外查FrameBufferFetch相关问题的时候看到Unity论坛上另一个贴子里面的回答。里面说到Unity支持了FrameBufferFetch,可是不支持DepthBuffer的获取。测试

参考网页:
https://forum.unity.com/threads/pixel-local-storage-and-frame-buffer-fetch-on-mobile-devices.604186/fetch

第二个问题,若是不增长Shader,目前没想到其余好的方法。
若是能够增长Shader,能够将原来的Shader复制一份,只在ShadowCaster的部分加一个“NeedDepth”这样的Tag,将水下的物体的材质球换成这个Shader,另外作一个只有ShadowCaster并带有“NeedDepth”这个Tag的Shader,这个Shader用来作Replace操做。

额外增长一个Camera,这个Camera跟随主相机,或者做为主相机的子节点,建立一个RT,让这个Camera渲染到这个RT,在Update里面使用ReplaceShader去画一下,那么只有有那个Tag的ShadowCaster会进行深度渲染,后续能够对这个RT进行编码等操做,这个RT记录的就是水下物体的深度。整个过程看上去没有特别多的额外工做,以为能够一试(我没有作过测试,但理论上是可行的)。

感谢Xuan@UWA问答社区提供了回答


Texture

Q:在UWA的《纹理优化:不只仅是一张图片那么简单》这篇文章中,描述了图片含有Alpha通道会对内存有影响。

经过如下的测试资源配置:

  • Tga_Alpha - 含有Alpha通道
  • Tga_NoAlpha - 不含有Alpha通道
  • Png_Trans - 含有透明的图片
  • 进入到Unity中的Format,所有代码设置为TextureImporterFormat.ASTC_6x6

测试结果:

  • 三张图片Unity所有Format为下图格式
  • 三张图片显示的内存大小所有同样
  • Texture Importer的Alpha Source设置为None,对测试结果无影响

    问题:图片是否含有Alpha通道,对于同一个Format格式,内存大小都是同样的吗?
    Tex.7z

A:原文中的优化建议是去除无心义的Alpha通道(原文中的定义为Alpha值所有为1的贴图),这个确实是对内存优化有帮助的。

题主的测试用例中,不管是png格式仍是tga格式,进入引擎后,都会被引擎转为内部的格式(RGBA、ETC、ASTC等)。设想一下,以ETC2为例,若是没有Alpha通道,在压缩质量能够接受的状况下,就能够选用RGB_Compressed_ETC2_4bits,而若是添加了这个无心义的Alpha通道,那么咱们在批量导入设置时,都会自动选择RGBA_Compressed_ETC2_8bits。这样内存就相差了一倍。

而问题中关于ASTC的状况,在Unity编辑器源码中的Texture导入格式的定义有这样一句注释:// ASTC uses 128bit block of varying sizes (we use only square blocks). It does not distinguish RGB/RGBA,即与是否包含Alpha通道无关。关于ASTC格式的介绍,这里推荐你阅读一下Github上的ASTC Format Overview

而关于你楼上回复中提到的Unity新版本的问题,能够看下Unity论坛上的这个问题

可能有人以为对于项目的贴图格式都是ASTC来讲,去除Alpha的意义不是很大,其实不能一律而论,虽然大小相同,但根据(https://zhuanlan.zhihu.com/p/158740249)中的测试,是否有Alpha通道会必定程度上影响压缩质量。因此仍是要在项目中合理使用。

感谢范君@UWA问答社区提供了回答

A2:游戏运行时Texture的Alpha通道要看导入后的状况,不能看源文件的状况。UWA本地资源检测对于Texture的Alpha通道检测的就是导入后的结果。

图片源文件的格式,图形硬件是不支持的,Unity也不直接接管。导入图片后,会按照Import Settings中的设置对图片进行处理,将图片导入成硬件支持的格式(在引擎中的格式),而在运行中使用的资源也是导入后的。

题主将Alpha Source设置为None,那么导入时就不对源文件的Alpha通道进行导入,而压缩格式为ASTC_6x6,这个格式是包含Alpha通道的。这样导入后三个资源都会默认生成一个全为1的Alpha通道。占用内存大小天然同样。

感谢Prin@UWA问答社区提供了回答


Rendering

Q:URP如何实现GrabPass的效果?URP管线已经去掉了原先GrabPass的功能,如今有一个扭曲特效的功能,相似热扰动那种。虽然URP可以直接获取到实体图作扭曲效果,可是像是半透明物体(好比:水、其余特效等)也须要被扭曲就作不到。

A:题主想要彻底实现GrabPass估计不行,可是能够有替代方案:

GrabPass的意思就是先绘制a物件,而后绘制b物件的时候影响a,绘制c物件的时候影响ab。注意,这最重要的是b物件的扰动影响不了c物件,由于b物件是比c物件先绘制的。

可是若是你可以接受b物件和c物件的扰动同时影响abc,那么就简单了,先用一个RT将扭曲的信息存下来(其实就是UV偏移),而后在Uber Shader中将偏移应用在画面上。这样扭曲信息就扰动了全部物件(不论是不透明仍是半透明)。

虽然不知道URP怎么实现的,可是咱们本身改的SRP,就是这么实现的。

感谢王烁@UWA问答社区提供了回答


Editor

Q:如今有一个继承于ScriptableObject的Asset,不管出于什么缘由,引用脚本的GUID错了。那么经过必定的编辑器脚本能找到这个Asset的Path,可是如何在ProjectView内选中它?

经测试,使用Selection.instanceID是能够选中的,而Instance ID通常须要经过Object来获取,可是由于脚本引用错误了,因此AssetDatabase是没法载入这个Object的。有什么办法或者API能获取到这个Instance ID呢?

A:经过查看公开源码,找到了一个可用的方法:

//assetPath : 某个找不到对应脚本的Asset实例路径
HierarchyProperty property = new HierarchyProperty(assetPath);
Selection.activeInstanceID = property.GetInstanceIDIfImported();

这样能够在ProjectView内正确选中了。

感谢题主黄程@UWA问答社区提供了回答


Addressable

Q:当下载好全部的资源后,在一个测试脚本中调用LoadAssetAsync函数,以下图:

在AssetBundleProvider这里是第一个疑惑:
既然Addressables所有采用缓存机制来存放AssetBundle包,那此处的File.Exists不是总会为False吗?

第二个疑惑在于:
Addressables在WebRequest完成下载后,如何把握把Bundle加载进内存的时机?也多是个人思路有问题,可是在后面的堆栈追踪里面没有发现有相似于LoadFromFile这样的调用。

A:这儿的File.Exists并非检查缓存,而是检查文件在不在StreamingAssets里面。而全部下载的资源则是经过缓存来获取的,若缓存里没有则下载。而Load这部分已经被封装在了UnityWebRequestAssetBundle内了。

感谢黄程@UWA问答社区提供了回:

封面图来源于网络


今天的分享就到这里。固然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,咱们早已在UWA问答网站上准备了更多的技术话题等你一块儿来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

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

相关文章
相关标签/搜索