求教关于unity d3d11中D3Dput fullscreenmode mode修改问题

unity的playerSetting中的D3D11 fullscreen & Mode的设置,通过脚本修改
您需要登录后才能查看回答!
1号核心群:
info@youke.proGDC2015: Networking for Physics Programmers&br&&a href=&///?target=http%3A////networking-for-physics-programmers-final-slides-gdc-2015/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/2015/&/span&&span class=&invisible&&03/03/networking-for-physics-programmers-final-slides-gdc-2015/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&
GDC2015: Networking for Physics Programmers
&img src=&/50/v2-581ccfc5cfe9e291a92306_b.png& data-rawwidth=&800& data-rawheight=&451& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/50/v2-581ccfc5cfe9e291a92306_r.png&&&h2&0x00 前言&/h2&&p&周末的时候在家看了下去年的Unite16 LA的视频。其中一个session很有趣,是AssetBundles开发团队Reichert的一个“总结过往,畅想未来”的名为《Future of Asset Bundles》的session 。&/p&&img src=&/v2-581ccfc5cfe9e291a92306_b.png& data-rawwidth=&800& data-rawheight=&451& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/v2-581ccfc5cfe9e291a92306_r.png&&&p&简而言之是过去的AssetBundles有很多问题,以后AssetBundles的API可能又会有一些很大的变化。当然,一个好消息是unity显然和微软一样,这两年已经意识到了开源的意义 一部分代码(高层c#部分的代码)在GitHub上已经开源:
&a href=&/?target=https%3A///Unity-Technologies/AssetBundles-Browser& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AssetBundles-Browser&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///Unity-Technologies/AssetBundles-BuildPipeline& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AssetBundles-BuildPipeline&i class=&icon-external&&&/i&&/a&
在开源社区内通过高频度的交流反馈推进项目的进度,而不是花几个月时间捂出来一个实验室里的怪胎,显然前者让人更有信心。&/p&&p&不过本文想要聊到主要内容并非AssetBundle,而是一个辅助工具——AssetBundles-Browser。&/p&&p&&br&&/p&&h2&0x01 过去的不足&/h2&&p&在这个session 中Reichert总结了若干过去AssetBundle的不足,抛开各种各种和性能或底层机制相关的不足不谈,我很认同的一点就是Editor内AssetBundle工具的缺位。&/p&&img src=&/v2-5cb8600eba499cbcb1d4_b.png& data-rawwidth=&800& data-rawheight=&427& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/v2-5cb8600eba499cbcb1d4_r.png&&&p&当然,Reichert罗列的问题还不止这些,他们甚至还组建了新的Asset Bundle & Build
Pipelin团队来处理解决这些已有的问题同时开发新的功能。其中当然包括了为我们这些开发者提供更多的Editor工具来处理AssetBundle的相关问题。&/p&&img src=&/v2-15fbe8cbaf6261b4_b.png& data-rawwidth=&1082& data-rawheight=&605& class=&origin_image zh-lightbox-thumb& width=&1082& data-original=&/v2-15fbe8cbaf6261b4_r.png&&&p&这其中包括一个叫做AssetBundles-Browser的工具,我感觉还是挺实用,因此在此和大家分享一下。&/p&&p&&br&&/p&&h2&0x02 AssetBundles-Browser&/h2&&p&&br&&/p&&img src=&/v2-a63cfadb34cf28a1ca8cb3dbf588f1bd_b.png& data-rawwidth=&850& data-rawheight=&344& class=&origin_image zh-lightbox-thumb& width=&850& data-original=&/v2-a63cfadb34cf28a1ca8cb3dbf588f1bd_r.png&&&p&
虽然AssetBundles-Browser是unity开发的一个工具,但是并没有包括在正式发布的Unity版本中。如果想要使用则必须保证Unity的版本在5.6+,并且去GitHub获取相应的脚本:
&a href=&/?target=https%3A///Unity-Technologies/AssetBundles-Browser& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AssetBundles-Browser&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&img src=&/v2-a58fea3b48b84d2f645b8ef0723ef62c_b.png& data-rawwidth=&525& data-rawheight=&204& class=&origin_image zh-lightbox-thumb& width=&525& data-original=&/v2-a58fea3b48b84d2f645b8ef0723ef62c_r.png&&&p&之后将获取的项目内的Editor文件夹拷贝到我们已有的项目中,就可以在Editor的Window菜单栏里找到&b&AssetBundle Browser&/b&了。
因为我的示例项目内没有Assetbundles,因此AssetBundle Browser窗口内空空如也。(场景以及模型资源来自:&a href=&/?target=https%3A//www./cn/%23%2521/content/35619& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Japanese Matsuri City&i class=&icon-external&&&/i&&/a&)&/p&&img src=&/v2-4acdcaccc883e441d2f987_b.png& data-rawwidth=&998& data-rawheight=&644& class=&origin_image zh-lightbox-thumb& width=&998& data-original=&/v2-4acdcaccc883e441d2f987_r.png&&&p&此时我们既可以像以往一样设置目标资源的Asset Labels,也可以直接将资源拖拽到AssetBundle Browser的Bundle列表区域。&/p&&p&例如,我可以直接将场景文件sample拖到AssetBundle
Browser的Bundle列表区域。这样一个Bundle就创建好了,它的Asset Labels也会被自动设置。在AssetBundle
Browser的右侧——Asset列表区域罗列了这个Bundle所包含的Asset。&/p&&img src=&/v2-bf20ada0c932c3f3d2d8fa_b.png& data-rawwidth=&900& data-rawheight=&633& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/v2-bf20ada0c932c3f3d2d8fa_r.png&&&p&我们可以很方便的定位目标Asset或者是按照体积对Asset进行排序,甚至检视是否有一些问题发生,比如某个资源是否被重复打包了。&/p&&p&所以接下来我们可以再次向Bundle列表区域拖拽一个需要被制作成Bundle的资源。这次我们发现,在Bundle列表和Asset列表都出现了一个黄色的提示——有四个资源被重复打包了。&/p&&img src=&/v2-c57c8e761ac605c90a7eda33e298deaa_b.jpg& data-rawwidth=&881& data-rawheight=&498& data-thumbnail=&/v2-c57c8e761ac605c90a7eda33e298deaa_b.jpg& class=&origin_image zh-lightbox-thumb& width=&881& data-original=&/v2-c57c8e761ac605c90a7eda33e298deaa_r.gif&&&p&那么怎么处理这种被重复引用的资源呢?我想各位在制作自己的AssetBundles时肯定都有各种各样的策略,不过在AssetBundle
Browser中处理这种依赖问题却很简单——无非是被重复引用的资源单独打包——创建一个新的Bundle用来存放那些重复引用的资源。&/p&&img src=&/v2-cb8cd44ae_b.jpg& data-rawwidth=&881& data-rawheight=&498& data-thumbnail=&/v2-cb8cd44ae_b.jpg& class=&origin_image zh-lightbox-thumb& width=&881& data-original=&/v2-cb8cd44ae_r.gif&&&p&当然,除了能往Bundle列表中拖拽来创建新的Bundle,那么我们能否直接在Asset列表中操作Bundle内的Asset呢?这同样是可以的。我们既可以直接将别的Asset拖入到某个Bundle内,也可以直接删除某个Bundle内的Asset。&/p&&img src=&/v2-09fdbcba9cb_b.jpg& data-rawwidth=&881& data-rawheight=&498& data-thumbnail=&/v2-09fdbcba9cb_b.jpg& class=&origin_image zh-lightbox-thumb& width=&881& data-original=&/v2-09fdbcba9cb_r.gif&&&p&&br&&/p&&p&&br&&/p&&h2&0x03 Build&/h2&&p&当AssetBundle的内容设置完成之后,我们就可以构建我们的Bundle文件了。我相信之前大家也是通过拓展编辑器来调用相应的BuildPipline的代码来构建Bundle文件,但是有了AssetBundle
Browser之后,我们可以很方便的在AssetBundle Browser的窗口内构建Bundle文件。&/p&&img src=&/v2-c193e42ad44d7acb519ae0e222e9835c_b.jpg& data-rawwidth=&881& data-rawheight=&498& data-thumbnail=&/v2-c193e42ad44d7acb519ae0e222e9835c_b.jpg& class=&origin_image zh-lightbox-thumb& width=&881& data-original=&/v2-c193e42ad44d7acb519ae0e222e9835c_r.gif&&&p&勾选适合自己使用的选项,选择适合自己的压缩算法都可以实现。&/p&&p&之后,我们就能看到生成的AssetBundles文件了。&/p&&p&是不是比之前方便了很多?&/p&&h2&ref:&/h2&&p&【1】&a href=&/?target=https%3A///Manual/AssetBundles-Browser.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AssetBundles-Browser Manual&i class=&icon-external&&&/i&&/a&&/p&&p&【2】slide可以到这里到这里下载:&a href=&/?target=http%3A///files/murongxiaopifu/UniteLA-AssetBundles.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UniteLA-AssetBundles.pdf&i class=&icon-external&&&/i&&/a&
各位如果觉得有趣的话,欢迎点个赞。&/p&&p&-华丽的分割线-
最后打个广告,欢迎支持我的书&a href=&/?target=https%3A///%25E5%259B%25BE%25E4%25B9%25A6/dp/B01LWUI34H/ref%3Dsr_1_12%3Fs%3Dbooks%26ie%3DUTF8%26qid%3D%26sr%3D1-12%26keywords%3Dunity& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity 3D脚本编程》&i class=&icon-external&&&/i&&/a&
&/p&&img src=&/v2-aec4df4f86ae6a51ca6013e7deb5a9bc_b.jpg& data-rawwidth=&522& data-rawheight=&668& class=&origin_image zh-lightbox-thumb& width=&522& data-original=&/v2-aec4df4f86ae6a51ca6013e7deb5a9bc_r.jpg&&&p&
欢迎大家关注我的公众号慕容的游戏编程:chenjd01&/p&&img src=&/v2-09dbc69f44eec82eeec07_b.png& data-rawwidth=&400& data-rawheight=&400& class=&content_image& width=&400&&&p&&/p&
0x00 前言周末的时候在家看了下去年的Unite16 LA的视频。其中一个session很有趣,是AssetBundles开发团队Reichert的一个“总结过往,畅想未来”的名为《Future of Asset Bundles》的session 。简而言之是过去的AssetBundles有很多问题,以后AssetBundles的A…
&p&在Shader中会使用各种不同图参与渲染,所以简单地总结下各种图的渲染原理、制作方法,最后面几种是程序生成图。&/p&
Albedo&/p&
Diffuse(Photographic)&/p&
&img data-rawwidth=&731& data-rawheight=&518& src=&/v2-2ab448bf1aafb5f77c96d9d_b.jpg& class=&origin_image zh-lightbox-thumb& width=&731& data-original=&/v2-2ab448bf1aafb5f77c96d9d_r.jpg&&&br&&p&从上图可以看出来,Albedo是去掉Diffuse的光照和阴影生成的,而在pbr工作流下必须要用Albedo。转换方法:&a href=&/?target=https%3A///watch%3Fv%3DKKQZN3eoKUo%26list%3DUUfyvlGW2gDNh5YH6CFh7BtQ& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How
to Make an Albedo Texture from a Diffuse Texture&i class=&icon-external&&&/i&&/a&&/p&
Alpha Map&/p&
&p&注意:jpg没有alpha通道,png也没有alpha通道,显示的alpha是根据rgb计算的灰度作为alpha使用。另外安卓平台ETC1也没有alpha通道。&/p&
Bump Map&/p&
Height Map&/p&
&p&基于高度的潮湿地面&/p&&img data-rawwidth=&721& data-rawheight=&388& src=&/v2-8093ccef2cf1c50b262357b_b.jpg& class=&origin_image zh-lightbox-thumb& width=&721& data-original=&/v2-8093ccef2cf1c50b262357b_r.jpg&&&br&&p&6.
Normal Map&/p&
&p&Bump Map是凹凸贴图,常用的有两种:一种是Emboss Bump Map(浮雕凹凸贴图,使用的Height Map),另一种是Dot3 Bump Map(点乘凹凸贴图,使用的是Normal Map)&/p&
Mask Map&/p&
&p&Mask用途比较多,常用来标识不同物体,比如标识建筑上反光的窗户、地面的积水、皮肤上汗水等。&/p&&img data-rawwidth=&716& data-rawheight=&241& src=&/v2-ec1b51ce8061df26fdbc91_b.jpg& class=&origin_image zh-lightbox-thumb& width=&716& data-original=&/v2-ec1b51ce8061df26fdbc91_r.jpg&&&br&&p&8.
Light Map(&a href=&/?target=https%3A///blog/powervr-gr6500-ray-tracing/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图来源&i class=&icon-external&&&/i&&/a&)&/p&
&img data-rawwidth=&545& data-rawheight=&352& src=&/v2-92a7b8ea634bfb03c8c87_b.jpg& class=&origin_image zh-lightbox-thumb& width=&545& data-original=&/v2-92a7b8ea634bfb03c8c87_r.jpg&&&br&&p&9.
&p&Lut(查找表lookup table)可以用于优化复杂光照的渲染,比如lambert blinn-phong可以把(NL,NH)作为uv坐标,将光照计算存储在一张贴图中,这样渲染时复杂的计算过程就优化为纹理采样了。另外皮肤、毛发之类复杂计算都可以用此方法优化。&/p&
Emission Map&/p&
&img data-rawwidth=&636& data-rawheight=&327& src=&/v2-4ca95ad00c9cf415efc4486_b.jpg& class=&origin_image zh-lightbox-thumb& width=&636& data-original=&/v2-4ca95ad00c9cf415efc4486_r.jpg&&&p&如果要表现更好的效果,自发光还要配合HDR/ToneMap/Bloom。&/p&
Metallic Map/Roughness&/p&
Specular Map/ Smoothness&/p&
&img data-rawwidth=&729& data-rawheight=&619& src=&/v2-6bb7e2df2da4fd9aabe6_b.jpg& class=&origin_image zh-lightbox-thumb& width=&729& data-original=&/v2-6bb7e2df2da4fd9aabe6_r.jpg&&&br&&a href=&/?target=https%3A///cgi-bin/frame_html%3Fsid%3DDqT4m2nuUaCTW0Yf%26r%3Dbaa48bcc49b2ae3f1ee527& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图来源&i class=&icon-external&&&/i&&/a&
&p&高光工作流可以不受限于PBR,能做非真实渲染,而金属工作流则对入门者更友好,限制在物理渲染的框架中,不至于渲染的太糟,当然金属工作流也可以做风格化的渲染。如果是用Substance Painter或者Marmoset Toolbag制作,这两种方式都支持导出的。&/p&
Gloss Map&/p&
Smothness Map&/p&
Roughness Map&/p&
&p&光泽贴图和高光贴图是不同的,它类似平滑贴图/粗糙贴图,表示物体表面的平滑粗糙程度,而高光贴图存储的是高光的强度,金属贴图存储的是金属度。&/p&
pbr(sbsar)&/p&
&img data-rawwidth=&760& data-rawheight=&389& src=&/v2-d27eadd735bbf18b1a44b_b.jpg& class=&origin_image zh-lightbox-thumb& width=&760& data-original=&/v2-d27eadd735bbf18b1a44b_r.jpg&&&p&17.
Ramp Map&/p&
&p&Ramp Map常用于卡通渲染,可以用于手工调节漫反、高光、阴影等,但是这比较依赖美术画图的功力,道理简单,渲染的好看却不容易。&/p&
&p&图来自米哈游的技术解说&a href=&/?target=https%3A///article/59169dfe1bc8e0ca/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&米哈游极乐净土的卡通渲染&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&769& data-rawheight=&522& src=&/v2-a7cf9f4fe327ab8beeda673_b.jpg& class=&origin_image zh-lightbox-thumb& width=&769& data-original=&/v2-a7cf9f4fe327ab8beeda673_r.jpg&&&br&&p&18.
Detail Map(Albedo Emission
Specular Normal 等)&/p&
&p&Detail Map主要解决相机靠近模型时贴图精度不足的问题,比如地面、皮肤、树木等等靠近看会很模糊,用一张尺度更小的坑坑洼洼的图来增加细节。左上是模糊的地面,右上是细节图,最下面是增加细节后的地面。&/p&&img data-rawwidth=&693& data-rawheight=&621& src=&/v2-50dd757aabbe35798a0cab5f0798ff24_b.jpg& class=&origin_image zh-lightbox-thumb& width=&693& data-original=&/v2-50dd757aabbe35798a0cab5f0798ff24_r.jpg&&&br&&p&19.
Gradient Map(用于Color
Gradient颜色分级、颜色校正等)&/p&
&img data-rawwidth=&519& data-rawheight=&369& src=&/v2-01cd8cfe86c0_b.jpg& class=&origin_image zh-lightbox-thumb& width=&519& data-original=&/v2-01cd8cfe86c0_r.jpg&&&p&20.
Jitter Map/Sparke Map/Glitter
&p&这种闪烁的噪点主要用于沙子、雪等渲染,主要用于表现颗粒感。这可以用噪声图来用于渲染,也可以用函数生成,一般类似frac(a*sin+b)这样形式,可以搭配WorldPos、ViewPos、Time来组合成函数。&/p&&img data-rawwidth=&772& data-rawheight=&431& src=&/v2-b1ad96c927a_b.jpg& class=&origin_image zh-lightbox-thumb& width=&772& data-original=&/v2-b1ad96c927a_r.jpg&&&br&&p&21.
Noise Map&/p&
&p&Noise有很多种:白噪声、蓝噪声、perlin噪声、simplex噪声、Voronoi噪声。另外推荐个噪声图编辑器:&a href=&/?target=http%3A///numberflow/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&numberflow&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&646& data-rawheight=&354& src=&/v2-f7f68a521e4cff3ddcf5a15_b.jpg& class=&origin_image zh-lightbox-thumb& width=&646& data-original=&/v2-f7f68a521e4cff3ddcf5a15_r.jpg&&&br&&p&22.
Splatting Map&/p&
&p&最常用于地形渲染,单独一张control texture作为多层贴图的混合系数,既可以用于颜色混合,也可以用于法线混合。&/p&
&img data-rawwidth=&769& data-rawheight=&532& src=&/v2-7d5e8df6fa91ce2a60ec086ebc1fbd05_b.jpg& class=&origin_image zh-lightbox-thumb& width=&769& data-original=&/v2-7d5e8df6fa91ce2a60ec086ebc1fbd05_r.jpg&&&br&&p&23.
Lens Map(Rain/Snow/Freeze/Glare/Flare/Flash/Gleam/starburst)&/p&
&p&做镜头效果会需要很多类似雨滴、雪花、脏迹、冰冻、炫光、星星等贴图。比如下面镜头雨滴。&/p&&img data-rawwidth=&679& data-rawheight=&784& src=&/v2-981bbaac_b.jpg& class=&origin_image zh-lightbox-thumb& width=&679& data-original=&/v2-981bbaac_r.jpg&&&p&24.
CubeMap&/p&
&p&Arm公司做的Ice Cave把CubeMap用在反射、折射、阴影,效果很赞(&a href=&/?target=http%3A///downloads/ARM_Game_Developer_Days/LondonDec15/presentations/IceCave_Rendering_Techniques_Optimized_For_Mobile.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ice
cave&i class=&icon-external&&&/i&&/a&)&/p&&img data-rawwidth=&770& data-rawheight=&429& src=&/v2-020bfca59a8ee7a24bbe3fd_b.jpg& class=&origin_image zh-lightbox-thumb& width=&770& data-original=&/v2-020bfca59a8ee7a24bbe3fd_r.jpg&&&br&&p&25.
MatCap Map&/p&
&p&Matcap的原理将法线转换view坐标系,取XY作为UV采样一张贴图,原理如下图&/p&&img data-rawwidth=&772& data-rawheight=&453& src=&/v2-5d3e9fd060c7c18bdfeb6_b.jpg& class=&origin_image zh-lightbox-thumb& width=&772& data-original=&/v2-5d3e9fd060c7c18bdfeb6_r.jpg&&&br&&p&对于场景色调比较统一、不要求精准光照的情况,这是种运行效率非常高的渲染方式。
&/p&&img data-rawwidth=&770& data-rawheight=&494& src=&/v2-8fe390cbf918_b.jpg& class=&origin_image zh-lightbox-thumb& width=&770& data-original=&/v2-8fe390cbf918_r.jpg&&&br&&p&26.
3D Texture&/p&
&p&3d纹理最常用于体渲染,比如云、高度雾等。Unity不支持3d纹理的文件格式,但是支持动态创建Texture3D,这样可以自己保存为asset格式或者自定义格式,在运行时转换为Texture3D。因为体渲染比较常用的方式是raymatching,步进次数少效果很难表现出来,在移动端效率比较低。图来&b&HorizonZeroDawn&/b&&/p&&img data-rawwidth=&769& data-rawheight=&263& src=&/v2-e58efc350dd818d9f33824_b.jpg& class=&origin_image zh-lightbox-thumb& width=&769& data-original=&/v2-e58efc350dd818d9f33824_r.jpg&&&br&&p&27.
Translucency Map(Thickness Map、反向AO、单散射)&/p&
&p&主要用于半透明物体,比如阔叶植被、玉等&/p&&img data-rawwidth=&711& data-rawheight=&486& src=&/v2-d88fabff292c2_b.jpg& class=&origin_image zh-lightbox-thumb& width=&711& data-original=&/v2-d88fabff292c2_r.jpg&&&br&&p&28.
Ambient Occlusion Map&/p&
&p&AO的计算方法是从顶点的半球发出射线,检测射线是否与网格相交,下图的遮挡值是5/7。&a href=&/?target=http%3A///twjcnblog/p/3753856.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图来源&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&436& data-rawheight=&341& src=&/v2-1511cb24bffef9b42d604de95fc458db_b.jpg& class=&origin_image zh-lightbox-thumb& width=&436& data-original=&/v2-1511cb24bffef9b42d604de95fc458db_r.jpg&&&br&&p&因为AO图噪点较多,即使增加射线的数量效果也不是很好,而体遮挡法能很好解决这个问题。AO如果作为后处理的话,SSVO、SSDO是比较流行的方法。&/p&&img data-rawwidth=&732& data-rawheight=&272& src=&/v2-9ce92e7568ffc6dec398_b.png& class=&origin_image zh-lightbox-thumb& width=&732& data-original=&/v2-9ce92e7568ffc6dec398_r.png&&&br&&p&29.
DUDV Map&/p&
&p&DuDv图看上去像蚯蚓爬过的法线图,一般用RG两个通道存储数据,是根据法线求导后再模糊处理存储的数据,类似与Parallax Map的用途,它也用于扭曲,比如下图用于扭曲水面倒影。&a href=&/?target=http%3A///wiki/DuDv_map& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图来源&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&766& data-rawheight=&212& src=&/v2-52da2db06b9af438470ae_b.jpg& class=&origin_image zh-lightbox-thumb& width=&766& data-original=&/v2-52da2db06b9af438470ae_r.jpg&&&br&&p&30.
Flow Map&/p&
&p&Flow map存储的是向量场数据,可以用于控制水面UV,比如下图石头周围一圈一圈水纹,制作工具有很多,比如&a href=&/?target=http%3A///discussion/105399/flowmap-painter& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&flowmap制作工具&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&666& data-rawheight=&292& src=&/v2-876652fcd20dcd_b.jpg& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-876652fcd20dcd_r.jpg&&&br&&p&31.
Ripple Map&/p&
&p&常用于雨滴水纹、物体落入水中的水纹等,可以算是flowmap的一种。&/p&&img data-rawwidth=&560& data-rawheight=&170& src=&/v2-135e70ad77b389e535edd80c930d3049_b.jpg& class=&origin_image zh-lightbox-thumb& width=&560& data-original=&/v2-135e70ad77b389e535edd80c930d3049_r.jpg&&&br&&p&32.
Distort Map&/p&
&p&扭曲图比较常用于半透物体,用于扭曲背景。比如下图冰块。&/p&&img data-rawwidth=&570& data-rawheight=&405& src=&/v2-c16ee11ddb9_b.jpg& class=&origin_image zh-lightbox-thumb& width=&570& data-original=&/v2-c16ee11ddb9_r.jpg&&&br&&p&33.
Displacement Map&/p&
Vector Displacement Map&/p&
&p&这两种图常用镶嵌,不过Displacement Map相当于高度图,而Vector Displacement Map存储的是三维向量,可以更好地细分模型。比如用地面蘑菇、地衣、耳朵等。&/p&&img data-rawwidth=&771& data-rawheight=&413& src=&/v2-33dd0fceac4a7cd_b.jpg& class=&origin_image zh-lightbox-thumb& width=&771& data-original=&/v2-33dd0fceac4a7cd_r.jpg&&&br&&p&35.
Radiosity Normal Map&/p&
&p&半条命首先引入的光照贴图方式,具体参考:&a href=&/?target=http%3A//www.decew.net/OSS/References/D3DTutorial10_Half-Life2_Shading.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Radiosity
Normal Map&i class=&icon-external&&&/i&&/a&,另外抵抗:人类陨落也有使用这种方法:&a href=&/?target=http%3A///tutorials/pages/lighting_rfom1.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&抵抗中的光照&i class=&icon-external&&&/i&&/a&&/p&
&img data-rawwidth=&708& data-rawheight=&537& src=&/v2-e70bcfc2bd5a53b71c8d6e9_b.jpg& class=&origin_image zh-lightbox-thumb& width=&708& data-original=&/v2-e70bcfc2bd5a53b71c8d6e9_r.jpg&&&p&36.
Cavity Map&/p&
&p&缝隙图存储的是比普通AO更小的AO信息,主要用于表现裂缝。制作方法参考:&a href=&/?target=http%3A///discussion/72813& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&缝隙图笔记&i class=&icon-external&&&/i&&/a&&/p&
&img data-rawwidth=&576& data-rawheight=&276& src=&/v2-c78d817e7f1ae8a35aae572b8ec45df4_b.jpg& class=&origin_image zh-lightbox-thumb& width=&576& data-original=&/v2-c78d817e7f1ae8a35aae572b8ec45df4_r.jpg&&&p&37.
Curvature Map&/p&
&p&曲率图和缝隙图不同的是它主要用于表现边缘、凹凸等效果,用于耳朵、眉骨、鼻子渲染效果会很好,利用DDX/DDY或fwidth也可以动态计算曲率。&/p&&img data-rawwidth=&273& data-rawheight=&250& src=&/v2-728a50436f1eacbaa62d0_b.jpg& class=&content_image& width=&273&&&br&&p&38.
Anisotropic Map&/p&
&p&有些物体的光照会呈现各向异性,比如头发、金属等,下图是三种头发渲染的方式(环形、kajiya、Scheuermann)都用到各向异性的贴图用于高光偏移。&/p&
&img data-rawwidth=&769& data-rawheight=&503& src=&/v2-6a4bdb3b17d682bc53b0ecf_b.jpg& class=&origin_image zh-lightbox-thumb& width=&769& data-original=&/v2-6a4bdb3b17d682bc53b0ecf_r.jpg&&&p&39.
Derivative Map&/p&
&p&这是由顽皮狗大神&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Morten Mikkelsen&i class=&icon-external&&&/i&&/a&首先提出法线图的衍生方式(&a href=&/?target=http%3A//jbit.net/%7Esparky/sfgrad_bump/mm_sfgrad_bump.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bump Mapping Unparametrized
Surfaces on the GPU&i class=&icon-external&&&/i&&/a&),因为用法线图一般在切线空间用于光照计算,而这种方法则不需要切线空间的参与,效率和效果都会更好,不用法线图,而是表面梯度图,和高度梯度图是不同的。不过这文章读起来挺心累的,最好参考Jim Blinn大神的&a href=&/?target=http%3A///pubs/7-blinn.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&凹凸贴图原理&i class=&icon-external&&&/i&&/a&。&/p&&img data-rawwidth=&713& data-rawheight=&580& src=&/v2-fb361ec18_b.jpg& class=&origin_image zh-lightbox-thumb& width=&713& data-original=&/v2-fb361ec18_r.jpg&&&br&&p&40.
Foam Map&/p&
&p&泡沫贴图、浪花贴图用于水面超过一定值时泡沫会和水面颜色混合,水面顶点越高泡沫透明度越大。&/p&&img data-rawwidth=&418& data-rawheight=&216& src=&/v2-6adf4cdfa4ebd538ec78b3e5_b.jpg& class=&content_image& width=&418&&&br&&a href=&/?target=http%3A///features/ocean-and-water-rendering-with-triton/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图来源&i class=&icon-external&&&/i&&/a&
Caustics Map&/p&
&p&水纹贴图:因为水面起伏、焦散导致水底某些地方会比周围更亮,可以用Projector渲染水纹,也可以参考GPU Gems的反向计算折射光线来采样太阳环境图的方法&a href=&/?target=http%3A//developer./books/HTML/gpugems/gpugems_ch02.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(Rendering Water Caustics)&i class=&icon-external&&&/i&&/a&,还有一个制作水纹的工具&a href=&/?target=https%3A//www.dualheights.se/caustics/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(水纹生成器+Unity
Demo)&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&736& data-rawheight=&367& src=&/v2-8e0c478babbcab1b39bd3_b.jpg& class=&origin_image zh-lightbox-thumb& width=&736& data-original=&/v2-8e0c478babbcab1b39bd3_r.jpg&&42.Bent Normal Map (经大神&a href=&/people/wang-teng-hao& class=&internal&&王滕昊&/a&提醒补充加上)&p&Bent Normal 常用于离线AO渲染中,是对原始法线修改后的向量,考虑周围遮挡情况使其指向光线传入的主方向,如下图Bend Normal 比原始法线偏右。用于光照计算或者环境光采样用Bend Normal在模型边缘处会得到更好的AO和光照效果。&br&&/p&&img src=&/v2-0ec60b580acd4ec3ecaad0dc8e983c4f_b.jpg& data-rawwidth=&481& data-rawheight=&236& class=&origin_image zh-lightbox-thumb& width=&481& data-original=&/v2-0ec60b580acd4ec3ecaad0dc8e983c4f_r.jpg&&&br&&p&43.
Depth Map&/p&
Camera Depth Map&/p&
Camera Depth Normal Map&/p&
&p&相机深度图可以用于渲染水、雾、扫描、半透物体等,这里有个不错文章有关深度法线图的:&a href=&/?target=http%3A///2013/11/unity-shaders-depth-and-normal-textures/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&深度与法线图&i class=&icon-external&&&/i&&/a&&/p&&img data-rawwidth=&694& data-rawheight=&425& src=&/v2-8ca53beb1bb_b.jpg& class=&origin_image zh-lightbox-thumb& width=&694& data-original=&/v2-8ca53beb1bb_r.jpg&&&br&&p&46.
Grab Pass Texture&/p&
&p&GrabPass可以用于热浪扭曲、半透冰块、冲击波等需要背景用于渲染的情况,在移动端效率不高,不要求动态背景时可以用Cubemap来代替。&/p&&img data-rawwidth=&470& data-rawheight=&776& src=&/v2-5cabfb047a18a579100dfc_b.jpg& class=&origin_image zh-lightbox-thumb& width=&470& data-original=&/v2-5cabfb047a18a579100dfc_r.jpg&&&br&&p&47.
Vertex Texture Fetch&/p&
&p&在Vertex Shader中读取上一帧水面高度纹理,在当前帧继续波动,这可以用于交互式水渲染,不过顶点纹理拾取是比较耗费资源的操作,不需要交互的水面是用不到的,对于海战类型的游戏会比较有用。&/p&&img data-rawwidth=&418& data-rawheight=&230& src=&/v2-6dd6b2fb6f_b.jpg& class=&content_image& width=&418&&
在Shader中会使用各种不同图参与渲染,所以简单地总结下各种图的渲染原理、制作方法,最后面几种是程序生成图。
Diffuse(Photographic)
从上图可以看出来,Albedo是去掉Diffuse的光照和阴影生成的,而在pbr工作流下必须要用Albedo。转换…
&img src=&/50/v2-d7ea9aa17016deea939d2da23d01b7ac_b.png& data-rawwidth=&885& data-rawheight=&426& class=&origin_image zh-lightbox-thumb& width=&885& data-original=&/50/v2-d7ea9aa17016deea939d2da23d01b7ac_r.png&&&b&一、基于Cubemap的动态软阴影&/b&&br&ARM公司曾利用Unity开发过两款技术Demo(&a href=&/?target=https%3A///graphics/unity/unity-demos& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ice Cave和Chess Room&i class=&icon-external&&&/i&&/a&),里面充分发挥了Cubemap的强大威力,既用来做地面反射、冰块折射,还用来做动态软阴影,利用简单的技术做出了高品质的画面。下面是Ice Cave的效果:&br&&img src=&/50/v2-f78f326fcdc4c4a377d9_b.jpg& data-rawwidth=&840& data-rawheight=&452& class=&origin_image zh-lightbox-thumb& width=&840& data-original=&/50/v2-f78f326fcdc4c4a377d9_r.jpg&&&br&&br&其中反射、折射部分参考:&a href=&/?target=https%3A///graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Reflections Based on Local Cubemaps in Unity&i class=&icon-external&&&/i&&/a&、&a href=&/?target=https%3A///graphics/unity/unity-guides-and-white-papers& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ARM Guide for Unity Developers&i class=&icon-external&&&/i&&/a&,下面主要介绍下软阴影部分原理。&br&以此国际象棋屋为例,屋子中间放置一个Reflect probe来拍摄周围环境,只用了Cubemap的RGB通道,而周围环境的Alpha其实也代表了光是穿透了窗户还是被墙壁遮挡,那就可以利用Cubemap剩余的Alpha通道就可以来存储光和周围环境的遮挡情况,Alpha通道图如下:&br&&img src=&/50/v2-8b1b3aff3a2d1e423b9f_b.png& data-rawwidth=&498& data-rawheight=&517& class=&origin_image zh-lightbox-thumb& width=&498& data-original=&/50/v2-8b1b3aff3a2d1e423b9f_r.png&&&br&&br&生成Cubemap细节可以参考AssetStore中的源码:&a href=&/?target=https%3A//www./cn/%23%21/content/61640& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&i class=&icon-external&&&/i&&/a&&br&利用生成的Cubemap渲染阴影主要分为两步,一是向量L(vertex-to-light)转换为Lp(校准过的vertex-to-light,用来采样Cubemap用),二是软阴影处理。&br&1.L到Lp向量校准:&br&输入参数:&br&_EnviCubeMapPos –
cubemap 中心坐标&br&_BBoxMax – 包围盒最大坐标,生成Cubemap时自动生成&br&_BBoxMin – 包围盒最小坐标,生成Cubemap时自动生成&br&V – 顶点坐标&br&L – vertex-to-light向量,已normalized &br&输出参数:&br&Lp – 校准后的vertex-to-light向量,作为UV去采样Cubemap&br&校准过程:&br&&img src=&/50/v2-4eaca156f5dc875c278a9b_b.png& data-rawwidth=&800& data-rawheight=&426& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/50/v2-4eaca156f5dc875c278a9b_r.png&&&br&&p&先利用线和包围盒求交点,从包围盒位置到交点的向量就是Lp,然后利用Lp去采样Cubemap用于着色。&/p&&img src=&/50/v2-07f3ef03df0b9b8e5211_b.jpg& data-rawwidth=&1892& data-rawheight=&1017& class=&origin_image zh-lightbox-thumb& width=&1892& data-original=&/50/v2-07f3ef03df0b9b8e5211_r.jpg&&&img src=&/50/v2-5204eea4efb7faba723541_b.png& data-rawwidth=&803& data-rawheight=&41& class=&origin_image zh-lightbox-thumb& width=&803& data-original=&/50/v2-5204eea4efb7faba723541_r.png&&&br&&p&另外背面要特殊处理下,防止阴影穿透问题。&/p&&img src=&/50/v2-c612e17a164e250ccc9cf_b.png& data-rawwidth=&794& data-rawheight=&83& class=&origin_image zh-lightbox-thumb& width=&794& data-original=&/50/v2-c612e17a164e250ccc9cf_r.png&&&img src=&/50/v2-9aefc43f24_b.png& data-rawwidth=&801& data-rawheight=&39& class=&origin_image zh-lightbox-thumb& width=&801& data-original=&/50/v2-9aefc43f24_r.png&&&br&&br&&p&2.软阴影:&/p&&p&阴影平滑的过程比较有趣,首先Cubemap过滤方式选择tri-linear filtering,然后计算vertex-to-intersection-point(顶点到交点)向量的长度,然后乘以外部传入系数:&/p&&img src=&/50/v2-1ad461f330ad31d7439bac881a498700_b.png& data-rawwidth=&798& data-rawheight=&35& class=&origin_image zh-lightbox-thumb& width=&798& data-original=&/50/v2-1ad461f330ad31d7439bac881a498700_r.png&&&img src=&/50/v2-c2b789e422ab067c45ae5fb9c033d649_b.png& data-rawwidth=&797& data-rawheight=&34& class=&origin_image zh-lightbox-thumb& width=&797& data-original=&/50/v2-c2b789e422ab067c45ae5fb9c033d649_r.png&&&br&&p&为了平滑阴影,我们用texCUBElod 去采样Cubemap,其中UV的XYZ来自Lp,W来自vertex-to-intersection-point(顶点到交点)的距离。&/p&&img src=&/50/v2-c53dd30e13dbf328d0fdf28_b.png& data-rawwidth=&796& data-rawheight=&67& class=&origin_image zh-lightbox-thumb& width=&796& data-original=&/50/v2-c53dd30e13dbf328d0fdf28_r.png&&&br&&p&下图也可以看到离窗户越远处的阴影越模糊。&/p&&img src=&/50/v2-ac7bdd3a36bf2_b.jpg& data-rawwidth=&1891& data-rawheight=&1018& class=&origin_image zh-lightbox-thumb& width=&1891& data-original=&/50/v2-ac7bdd3a36bf2_r.jpg&&&br&&p&这种做阴影方法的限制是比较适合室内环境、点光源位置不变、内部有移动物体的情况。&/p&&br&&b&二、地面云阴影&/b&&br&对于地面上云阴影,用实时灯光照射出阴影显然是不划算,可以直接在地面shader中混合一个运动的云图就能达到类似效果。&br&&img src=&/v2-b1adbd31eaae747fd25d53_b.jpg& data-rawwidth=&837& data-rawheight=&505& data-thumbnail=&/50/v2-b1adbd31eaae747fd25d53_b.jpg& class=&origin_image zh-lightbox-thumb& width=&837& data-original=&/50/v2-b1adbd31eaae747fd25d53_r.gif&&&br&gif图显示不了,看这里吧:&a href=&/?target=http%3A///blog/704/72-.gif& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&云阴影&i class=&icon-external&&&/i&&/a&&br&我用shaderforge拖出了一个简单的版本&br&&img src=&/50/v2-00e0d67c0c0e363d3035c_b.jpg& data-rawwidth=&880& data-rawheight=&535& class=&origin_image zh-lightbox-thumb& width=&880& data-original=&/50/v2-00e0d67c0c0e363d3035c_r.jpg&&&br&另外这种方法也可以用来做地面风雪效果。&br&&b&三、植物摇曳阴影&/b&&br&&b&对于树、草、旗子这类位置不变但有摇曳动画的物体,可以预先把阴影烘焙到贴图中,然后把阴影图作为单独贴图、或地面贴图Alpha通道传送到地面shader中,然后只需要添加阴影晃动的特性的就可以,随植物晃动而晃动,会有一种真实阴影的感觉。另外注意阴影的方向、和植物晃动的同步登细节。&/b&&br&&img src=&/v2-75aadaad351_b.jpg& data-rawwidth=&200& data-rawheight=&200& data-thumbnail=&/50/v2-75aadaad351_b.jpg& class=&content_image& width=&200&&&br&&img src=&/v2-391d30adb11_b.jpg& data-rawwidth=&200& data-rawheight=&200& data-thumbnail=&/50/v2-391d30adb11_b.jpg& class=&content_image& width=&200&&&br&具体细节可以参考:&a href=&/?target=http%3A///program/translateview/7167597& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&手机游戏中大量植物图像的伪阴影渲染&i class=&icon-external&&&/i&&/a&&br&&br&&b&四、结合Projector和Rendertexture的实时阴影&/b&&br&创建一个跟随主相机的阴影相机,改为正交投影,设置单独的shadow Layer,将需要投射阴影物体设置到shadow layer,为此阴影相机设置渲染目标到一个渲染纹理RTT_Shadow。另外创建一个Projector,为它设置一个材质Mat_Proj,并将RTT_Shadow传到Mat_Proj的shader中进行着色,另外为防止投影相机边缘的刺刺的长线,要设置一个阴影衰减纹理,如果需要软阴影则需要另外Blur。&br&&img src=&/50/v2-f1620b8dcd1fed35c6f6_b.png& data-rawwidth=&295& data-rawheight=&282& class=&content_image& width=&295&&&br&&br&&b&这是最近几年手游应用比较广泛的方法,网上有很多相关文章,比如:&a href=&/?target=http%3A//blog.csdn.net/mobilebbki399/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&结合Projector和Rendertexture实现实时阴影&i class=&icon-external&&&/i&&/a&、&a href=&/?target=http%3A//blog.csdn.net/aceyan0718/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ProjectorShadow(手游上的实时阴影方案)&i class=&icon-external&&&/i&&/a&&/b&&br&&b&另外AssetStore也有不少类似插件:&a href=&/?target=https%3A//www./en/%23%21/content/14746& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Fast Shadow Projector&i class=&icon-external&&&/i&&/a&&/b&&br&&br&&img src=&/50/v2-59f34d3a761abfde1d979_b.png& data-rawwidth=&658& data-rawheight=&349& class=&origin_image zh-lightbox-thumb& width=&658& data-original=&/50/v2-59f34d3a761abfde1d979_r.png&&&br&&b&五、角色脚下阴影面片&/b&&br&&b&对于游戏中的NPC、杂兵、野怪这些非关键性角色可以直接用防止一个阴影面片来模拟阴影,当然如果地面起伏比较大可能会有穿插问题。&/b&&br&&img src=&/50/v2-c2bcbbfe4cb9e3e5b7d27_b.png& data-rawwidth=&412& data-rawheight=&253& class=&content_image& width=&412&&&br&&br&&br&&b&六、Light Probe&/b&&br&&b&具体细节参考Unity手册不赘述了:&a href=&/?target=https%3A///Manual/LightProbes.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Light Probes&i class=&icon-external&&&/i&&/a&&/b&&br&&img src=&/50/v2-5cea3c872a951a48becdfdeda9e682d7_b.png& data-rawwidth=&525& data-rawheight=&333& class=&origin_image zh-lightbox-thumb& width=&525& data-original=&/50/v2-5cea3c872a951a48becdfdeda9e682d7_r.png&&&br&&br&&br&&b&七&/b&&b& Shadow Maps&/b&&br&1.Standard Shadow Mapping:的基本思想是在光源位置放置一个相机(Light space Camera),画一遍深度得到深度图,在渲染场景时将pixel坐标转换Light Space计算深度,然后比较它深度和深度图中的深度,如果比深度图中深度大就意味着在阴影中,否则在被照亮。&br&阴影的锯齿有两类:透视导致的锯齿(Perspective alias)和投影导致的锯齿(Project alias)。&br&2.PCF:投影导致的锯齿是因为灯光投射方向和物体表面夹角过小时多pixel对应阴影图的一个texel,这可以通过提高阴影图的大小来解决,也可以通过Percentage Closer Filtering来柔化边缘。PCF就是在绘制时,除了绘制当前点还会对周围像素进行多次采样、混合来柔化锯齿,常用PCF有:&a href=&/?target=http%3A//blog.csdn.net/candycat1992/article/details/8981370& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用随机采样实现soft shadow&i class=&icon-external&&&/i&&/a&、&a href=&/?target=http%3A//www.ownself.org/blog/2010/percentage-closer-filtering.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&泊松采样&i class=&icon-external&&&/i&&/a&等。&br&&img src=&/50/v2-af48c91ce1e6b0699719_b.png& data-rawwidth=&630& data-rawheight=&246& class=&origin_image zh-lightbox-thumb& width=&630& data-original=&/50/v2-af48c91ce1e6b0699719_r.png&&&br&&br&3.PSM:透视导致的锯齿是因为透视的近大远小所带来的,于是就有了Perspective Shadow Map,它将整个Shadow Map的计算过程转到归一化设备空间(NDC)来计算,这就消除了近大远小的问题。下图是Standard Shadow Map和经过Perspective Shadow Map优化过的阴影,阴影明显更细致。&br&&img src=&/50/v2-8f5f51b8c50cf6492b1a_b.png& data-rawwidth=&257& data-rawheight=&255& class=&content_image& width=&257&&&img src=&/50/v2-e5c250abf748fb61e244f1b_b.png& data-rawwidth=&257& data-rawheight=&254& class=&content_image& width=&257&&&br&&br&可是PSM本身有很大局限性,比如影子质量比较依赖视角方向、近处阴影与远处阴影Z分布过大。&br&4.LISPSM:在PSM的基础上又有了新的阴影技术Light Space Perspective Shadow Maps,它是在和灯光方向垂直的方向构建View Frustrum,然后将灯光、场景都转到这个View Frustrum的Perspective space,然后再计算Shadow Map,这样无论是点光、聚光、平行光就都转为平行光。&br&&img src=&/50/v2-af5dc888a3ad3a_b.png& data-rawwidth=&550& data-rawheight=&351& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&/50/v2-af5dc888a3ad3a_r.png&&&br&&br&左图是Uniform(近处精度不足),中间是LISPSM(近处、远处都不错),右面是PSM(远处精度不足)。&br&LISPSM具体细节参考:&a href=&/?target=https%3A//www.cg.tuwien.ac.at/research/vr/lispsm/shadows_egsr2004_revised.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&cg.tuwien.ac.at/researc&/span&&span class=&invisible&&h/vr/lispsm/shadows_egsr2004_revised.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&5.VSM(方差阴影):在使用PCF时一般不能提前对Shadow Map进行模糊处理,因为这会导致PCF计算不准,而Variance Shadow Maps则没有这样的限制。VSM存储的Shadow Map不近包括深度,还有深度的平方,这时可以对Shadow Map做过滤,然后利用切比雪夫不等式计算出大于当前深度的概率上限,也就是阴影区的概率。切比雪夫不等式:&br&&img src=&/50/v2-ab83bbb8af_b.png& data-rawwidth=&307& data-rawheight=&117& class=&content_image& width=&307&&&img src=&/50/v2-864f0daf2f6addb6b09748_b.png& data-rawwidth=&397& data-rawheight=&117& class=&content_image& width=&397&&&img src=&/50/v2-9bd51fccdea69ea30cca6_b.png& data-rawwidth=&367& data-rawheight=&329& class=&content_image& width=&367&&&img src=&/50/v2-6d8c02975fef6baaefcd57_b.png& data-rawwidth=&367& data-rawheight=&329& class=&content_image& width=&367&&&br&&br&&br&&br&左图是Standard Shadow Map,右图是Variance Shadow Map&br&具体细节参考:&a href=&/?target=http%3A//developer./whitepapers/2007/SDK10/VarianceShadowMapping.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Variance Shadow Mapping&i class=&icon-external&&&/i&&/a&、&a href=&/?target=http%3A//www.punkuser.net/vsm/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VSM的demos&i class=&icon-external&&&/i&&/a&、&a href=&/?target=https%3A//graphics.stanford.edu/%7Emdfisher/Shadows.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Matt's Variance Shadow Maps&i class=&icon-external&&&/i&&/a&&br&6、CSM/PSSM:这是两种分别研究发表但是原理几乎一样的阴影技术,Unity用的就是CSM,而其中PSSM是几个中国人(Zhang F, Sun H Q, Xu L L, et al,&a href=&/?target=http%3A//cs./cs/xyxw/webinfo/5.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&观摩大佬风采&i class=&icon-external&&&/i&&/a&)提出的。它们的原理如下:&br&a)对摄像机视锥体内沿着Z由近到远切阴影图分为多张,而切分是两种切分规则的混合,一种是均匀切分,一种是指数切分,两者按照一定比率混合起来。&br&&img src=&/50/v2-0ae72a1c96be00c26f57ad_b.png& data-rawwidth=&417& data-rawheight=&222& class=&content_image& width=&417&&&br&&br&b)对每一块分别计算一个光源投影空间内平移、缩放的矩阵cropMatrix,它可以将切分的多块移动、缩放到光源的视椎中,这个矩阵和正交投影矩阵非常像。&br&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
// Build a matrix for cropping light's projection
// Given vectors are in light's clip space
Matrix Light::CalculateCropMatrix(Frustum splitFrustum)
Matrix lightViewProjMatrix = viewMatrix * projM
// Find boundaries in light's clip space
BoundingBox cropBB = CreateAABB(splitFrustum.AABB,
lightViewProjMatrix);
// Use default near-plane value
cropBB.min.z = 0.0f;
// Create the crop matrix
float scaleX, scaleY, scaleZ;
float offsetX, offsetY, offsetZ;
scaleX = 2.0f / (cropBB.max.x - cropBB.min.x);
scaleY = 2.0f / (cropBB.max.y - cropBB.min.y);
offsetX = -0.5f * (cropBB.max.x + cropBB.min.x) * scaleX;
offsetY = -0.5f * (cropBB.max.y + cropBB.min.y) * scaleY;
scaleZ = 1.0f / (cropBB.max.z - cropBB.min.z);
offsetZ = -cropBB.min.z * scaleZ;
return Matrix( scaleX,
&/code&&/pre&&/div&c)针对切分的每一块渲染阴影图,一般阴影图大小一样的,比如都是,而近处包含的场景范围比远处小,所以近处阴影图的精度会更高。&br&d)渲染场景阴影&br&&img src=&/50/v2-0a754fdc0baf96ab509c53_b.jpg& data-rawwidth=&500& data-rawheight=&294& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/50/v2-0a754fdc0baf96ab509c53_r.jpg&&&br&&br&关于CSM和PSSM具体细节参考:&a href=&/?target=https%3A///en-us/library/windows/desktop/eev%3Dvs.85%29.aspx& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cascaded Shadow Maps&i class=&icon-external&&&/i&&/a&、&a href=&/?target=https%3A//www.researchgate.net/publication/_Parallel-split_shadow_maps_for_large-scale_virtual_environments& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Parallel-split shadow maps for large-scale virtual environments&i class=&icon-external&&&/i&&/a&、&a href=&/?target=https%3A///gpugems/GPUGems3/gpugems3_ch10.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PSSM from GPU Gems 3&i class=&icon-external&&&/i&&/a&&br&另外Shadow Maps还有很多其他变种:&a href=&/?target=http%3A//hyzgame.blogspot.jp/2009/04/sm.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&已知Shadow Maps名称汇总&i class=&icon-external&&&/i&&/a&
一、基于Cubemap的动态软阴影 ARM公司曾利用Unity开发过两款技术Demo(),里面充分发挥了Cubemap的强大威力,既用来做地面反射、冰块折射,还用来做动态软阴影,利用简单的技术做出了高品质的画面。下面是Ice Cave的效果: 其中反射、…
&img src=&/50/v2-88db6bd5daad72e02f412_b.png& data-rawwidth=&800& data-rawheight=&499& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/50/v2-88db6bd5daad72e02f412_r.png&&&p&原文链接:&a href=&/?target=http%3A///archives/QA_ResourceManagement.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&关于Unity中的资源管理,你可能遇到这些问题 - Blog&i class=&icon-external&&&/i&&/a&&/p&&p&在优化Unity项目时,对资源的管理可谓是个系统纷繁的大工程。鉴于Unity独特又绝(cao)妙(dan)资源打包的AssetBundle管理机制,不同资源的属性适合于不同的存储和加载方式。此外,要处理好成百上千个资源之间的相互依赖关系也非易事。谁说良好的资源管理不是个艺术呢?:)&/p&&p&——————————————————&/p&&p&&strong&关键字&/strong&&br&&/p&&p&&strong&AssetBundle&/strong&&br&&strong&资源制作 纹理\网格\材质\Shader\音频\动画&/strong&&br&&strong&Lightmap&/strong&&/p&&h2&&strong&一、AssetBundle 相关&/strong&&/h2&&p&&strong&Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了。而且我把图片都打成了Bundle,然后读取出来,图片的大小应该是超过了这个SerializedFile的大小的?&/strong&&br&&/p&&img src=&/v2-19ebf822a59694eebb0d97_b.jpg& data-rawwidth=&949& data-rawheight=&297& class=&origin_image zh-lightbox-thumb& width=&949& data-original=&/v2-19ebf822a59694eebb0d97_r.jpg&&&br&&blockquote&&p&SerializedFile是AssetBundle加载时产生的序列化信息,一般为LoadFromCacheOrDownload、LoadFromFile和New WWW加载本地AssetBundle文件所致。如果AssetBundle中的资源已经加载,且后续没有依赖该AssetBundle的资源进行加载,那么可以通过Unload(false)将其删除。SerializedFile中记录的是AssetBundle的序列化信息,而不是其包含资源的内容,因此,其大小要小于或远小于资源的实际内存。&/p&&/blockquote&&p&&strong&Q2:我们现在采取了2种资源管理方式, 我想了解下内存占用问题。 方式A:AssetBundle加载好以后在内存中保留, 如果需要创建对象就通过Instantiate来创建。方式B:AssetBundle加载好以后立刻通过Instantiate实例化一个对象, 然后Unload(false)这个AssetBundle,如果需要,创建对象通过clone来完成。对于方式A,在Profiler中发现 WebStream中有相关AssetBundle文件存在, 我们认为这份内存是多余的, 所以就采取了方式B, 方式B又面临资源卸载不干净的情况。想确认一个问题, 如果采取方式A: 一个 xxx.assetBundle原始文件大小是 1MB, 解压到Webstream内存中是2MB, 最终实际内存占用是2MB 还是3MB 呢?&/strong&&/p&&blockquote&&p&如果采取方式A:最终实际内存占用是2MB,而不是3MB,WebStream中已经包含原始AssetBundle的数据。对于没有依赖关系的AssetBundle文件,我们推荐方式B的形式对AssetBundle进行卸载,这样可以免除不必要的内存占用,对于这种方式加载出来的资源,可以通过Resources.UnloadAsset和Resources.UnloadUnusedAssets来进行卸载,如果无法卸载,则该资源一定被缓存了,研发团队可通过检测自己的缓存池/Constainer来进行检测。同时,如果是Unity 5.3以后版本,可尝试通过Memory Profiler来进一步查看。&/p&&/blockquote&&p&&strong&Q3:打包时候AssetBundle的md5总变化(被打包的东西没变),请问能怎么解决?有说法是加上DeterministicAssetBundle就可以,但是我尝试后发现md5依然变化。&/strong&&/p&&blockquote&&p&该方法确实并不受用。对于Unity 4.x版本的AssetBundle文件,其md5值在某些情况下确实会前后不一致(哪怕是完全一样的内容进行打包)。对于该系列版本,仅能建议开发团队建立配置文件来对AssetBundle进行管理。&br&而对于Unity 5.x版本,则可以在打包时开启 AppendHashToAssetBundleName 选项,这样Unity引擎会在每个AssetBundle文件后生成一个唯一的HashID(显示地放在文件名后),开发团队可以通过该ID来判断对应的AssetBundle文件是否发生改变。&/p&&/blockquote&&p&&strong&Q4:如果采用依赖打包的话,比如NGUI,图集A作为被依赖包,界面1、2、3作为独立包,分别依赖打包。当图集A重新打包的时候,是不是界面1、2、3也都要重新打包?目前我们是界面打包时清空全部的图集信息再打包,在客户端加载后再动态赋值回来。这样可以实现单独更新图集,但是代价就是加载的性能。请问有什么更好的解决方案呢?&/strong&&/p&&blockquote&&p&“当图集A重新打包的时候,是不是界面1、2、3也都要重新打包”,这是不需要的,Unity 4.x的依赖打包的限制在于,在重新打一个包时需要将它依赖的包都重新打一次,但不需要重打依赖它的包。&/p&&/blockquote&&p&&strong&Q5:请问内置的shader怎么打包?我用到了内置材质球,不只是Shader,这时候在Profiler中看到加载的结果中会出现多份,如下图所示&/strong&&br&&img src=&/v2-d3c8bae384a4da8f26dd2f00c723b59e_b.png& data-rawwidth=&223& data-rawheight=&509& class=&content_image& width=&223&&&br&&/p&&blockquote&&p&通常有两种方式对内置的Shader进行打包:&/p&&ol&&li&将其添加到Graphics Settings中的Always Included Shaders 中,此时添加后的内置Shader就不会被打入AssetBundle包中;&/li&&li&在&a href=&/?target=http%3A///cn/get-unity/download/archive& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity - Get Unity - Download Archive&i class=&icon-external&&&/i&&/a&下载内置的 Shader,将其导入项目,并替换成非内置的材质球,从而可以直接通过脚本来控制其打包的方式。&/li&&/ol&&/blockquote&&p&&strong&Q6:请问粒子特效的Shader是否不能使用依赖打包? 我们对Shader的模型和特效使用了依赖打包,运行的时候发现模型显示是正常的,但是粒子特效使用的Shader就不能正常运行,特效显示不正常。而在编辑器中,我们看到Material中的Shader是存在的。这时候如果重新手动给这个Material指定同样的Shader,这个粒子特效就能正常显示,请问这是什么原因引起的?&/strong&&/p&&blockquote&&p&部分 Shader 在打包到 Android 版本的 Assetbundle 之后,会因为平台不兼容而无法正确显示,这是因为打包后的 Shader 代码只保留了目标平台的预编译代码,不一定能够在 Editor 下运行,所以这是正常现象。 但这并不会影响依赖打包,因为在真机上并不会出现类似的问题。&/p&&/blockquote&&p&&strong&Q7:Resource的场景下有两个场景Scene1.unity和Scene2.unity。我要对这些文件进行打包,生成了&/strong&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Scene1.assetbundle
Scene1.assetbundle.meta
Scene2.assetbundle
Scene2.assetbundle.meta
&/code&&/pre&&/div&&p&&strong&如果我有相同的资源,理论上它会在这两个包里各存一份,这样就造成了包体过大。所以有没有办法把共享资源做成依赖项单独打包,这样的话每个场景就不会过大了。Unity 5.x的BuildAssetBundles打包机制是否和Unity 4.x不一样?原来的打包机制已经被剔除了吗?&/strong&&/p&&blockquote&&p&用Unity 4.x 的 Push/Pop 是可以抽出相同的资源,并且据我们所知该方法在Unity 5.x 中也受用。根据Unity 5.x新的打包机制,只要把相同资源的 AssetBundle Name 设置好,打包时就会自动抽出来。&/p&&/blockquote&&p&&strong&Q8:现在生成AssetBundle的时候每个文件会多生成一个Manifest文件,这个文件也需要一起随着AssetBundle上传吗,在资源加载的时候具体怎么用呢?&/strong&&/p&&blockquote&&p&每个文件多生成的Manifest 文件是不需要上传的,其作用就是供开发人员查看AssetBundle 中的依赖关系等信息。&br&但除了每个文件多生成的 Manifest 以外,根目录下还会有一个与根目录同名的AssetBundle 以及 Manifest 文件,通过运行时加载这个AssetBundle,可以得到一个 AssetBundleManifest 对象,然后就可以通过这个对象得到AssetBundle直接的依赖关系。&br&更多信息可以参考&a href=&/?target=http%3A///ScriptReference/AssetBundleManifest.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AssetBundleManifest&i class=&icon-external&&&/i&&/a&&/p&&/blockquote&&p&&strong&Q9:如果我有一个Prefab,它的Dependencies都在Resources文件夹中,那么,当我在AssetBundle打包时,只打包这个Prefab(不指定pleteAssets和BuildAssetBundleOptionsCollectDependencies)的话,这个Prefab能够正确实例化吗?&/strong&&/p&&blockquote&&p&这是不能正确实例化的,因为AssetBundle中的资源和Resource文件夹下资源是不会建立依赖关系的(脚本除外,因为开启BuildAssetBundleOptionsCollectDependencies 时,脚本依然不会打包到AssetBundle中)。所以会出现Mesh、Material等的丢失。&/p&&/blockquote&&p&&strong&Q10:我们通过AssetBundle预加载Shader后,并没有卸载AssetBundle,但是发现后面加载的Object并没有引用到正确的Shader,这可能是由于什么原因呢?&/strong&&/p&&blockquote&&p&很可能是项目中AssetBundle的依赖关系打包不正确。后续加载的AssetBundle都需要与Shader的AssetBundle文件进行依赖,这样Unity引擎才会在加载后续AssetBundle时,将Shader进行关联。&br&建议开发团队通过UWA资源检测来检测下AssetBundle文件的依赖关系。主要查看两处,一个是Shader是否被冗余打包;一个是其& 他的AssetBundle是否与Shader的AB进行正确的依赖。具体检测效果如下:&br&&img src=&/v2-e1d8f8b4a63c61d59d9ddab_b.png& data-rawwidth=&2334& data-rawheight=&1470& class=&origin_image zh-lightbox-thumb& width=&2334& data-original=&/v2-e1d8f8b4a63c61d59d9ddab_r.png&&&br&如下图红框所示,开发团队可以直接查看Shader以及其他资源在AssetBundle包中的冗余情况。&/p&&img src=&/v2-ea7edae7cf7184_b.png& data-rawwidth=&2336& data-rawheight=&1514& class=&origin_image zh-lightbox-thumb& width=&2336& data-original=&/v2-ea7edae7cf7184_r.png&&&/blockquote&&p&&strong&Q11:我游戏里重复的特效较多,有些只是图案相同但改变了颜色参数,如果都打成独立AssetBundle,则内存里面会有多份Texture。关于这样的打包一般有什么推荐的方法呢?&/strong&&/p&&blockquote&&p&如果是相同内容且仅是整体颜色不同的话,那么建议项目中只保留一份初始纹理资源,并通过Shader在运行时改变其整体配色,从而达到不同的效果。但如果是局部配色不同,那么可以在原始纹理的基础上加一种或几种Mask纹理,用来负责颜色的自适应调配,然后再通过Shader来达到不同的展示效果。&/p&&/blockquote&&p&&strong&Q12:请问一下,我两个预设都引用了第三个AssetBundle的贴图,如果不希望这张贴图存在两份,一定要等这两个预设都加载好了,才能卸载贴图的AssetBundle吗 ?&/strong&&/p&&blockquote&&p&是的,但并不是因为这样做会使“这张贴图存在两份”,而是因为如果先卸载贴图的AssetBundle会导致后续加载两个预设时会丢失依赖,即找不到贴图。如果脚本中会对这个情况进行检查并重新加载贴图的AssetBundle,那么此时才会造成“这张贴图存在两份”的问题。&/p&&/blockquote&&p&&strong&Q13:UGUI的图集操作中我们有这么一个问题,加载完一张图集后,使用这个方式获取其中一张图的信息:assetBundle.Load (subFile, typeof (Sprite)) as S 这样会复制出一个新贴图(图集中的子图),不知道有什么办法可以不用复制新的子图,而是直接使用图集资源 。&/strong&&br&&img src=&/v2-8a2b8bf787c94d31513bdf01d13f47ca_b.png& data-rawwidth=&898& data-rawheight=&586& class=&origin_image zh-lightbox-thumb& width=&898& data-original=&/v2-8a2b8bf787c94d31513bdf01d13f47ca_r.png&&&br&&/p&&blockquote&&p&经过测试,这确实是 Unity 在 4.x 版本中的一个缺陷,理论上这张“新贴图(图集中的子图)”是不需要的,并不应该加载。 因此,我们建议通过以下方法来绕过该问题:&br&在 assetBundle.Load (subFile, typeof (Sprite)) as S 之后,调用&br&Texture2D t = assetBundle.Load (subFile, typeof (Texture2D)) as Texture2D;&br&Resources.UnloadAsset(t);&br&从而卸载这部分多余的内存。&/p&&/blockquote&&p&&strong&Q14:下图一是刚进游戏时获取的信息,第二张是开关几次同一个UI界面后获取,对比两图我们发现有多份重复的Texture。请问这是为什么?我们的加载方式是UI通过AssetBundle加载,加载后会释放AssetBundle,然后再次加载 UI 就会造成纹理资源的冗余。&/strong&&br&&img src=&/v2-1ec60dd47ebed7d656dabb9_b.jpg& data-rawwidth=&797& data-rawheight=&662& class=&origin_image zh-lightbox-thumb& width=&797& data-original=&/v2-1ec60dd47ebed7d656dabb9_r.jpg&&&img src=&/v2-3f8315dee2fc528a632a39f3d030a478_b.jpg& data-rawwidth=&849& data-rawheight=&662& class=&origin_image zh-lightbox-thumb& width=&849& data-original=&/v2-3f8315dee2fc528a632a39f3d030a478_r.jpg&&&br&&/p&&blockquote&&p&刚进游戏时获取的图中出现的“重复”资源可能并不是冗余,因为 Atlas的一个 Group 中可能包含多张一样大小的Page(即纹理),而这几个Page在内存中的名字是一样的。&br&但是,如果同一UI界面多次开启后,内存中出现了更多同样的资源,则说明UI的管理方式存在一定问题。对于频繁使用的UI,我们建议在加载之后通过缓冲池对其进行缓存,后续使用时,直接通过缓冲池获取即可。而不要每次均通过AssetBundle进行加载,这种做法既会造成更大的CPU占用,同样会很大几率造成资源的冗余。&br&同时,如果多次开启的是不同UI界面,并且造成内存中同种资源的增加,则很有可能是UI在AssetBundle打包时形成了冗余(这种情况在目前的UGUI系统中较为常见)。对此,如果开发团队使用的是UGUI,那么我们的建议如下:&/p&&ol&&li&对于使用Unity 5.x的新AssetBundle打包系统,则打包时尽可能将同种Atlas的UI界面打成一个AssetBundle文件,否则将很有可能出现资源冗余的情况;&/li&&li&对于使用Unity 4.x的老AssetBundle打包系统,则可以将一个含有Atlas的Prefab(或其他Object)先打包,其他UI元素对其进行依赖即可。&/li&&/ol&&p&此外,开发团队可以考虑用 &a href=&/?target=http%3A//WWW.LoadFromCacheOrDownload& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&WWW.LoadFromCacheOrDownload&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 来加载共享包,因为 new WWW 的方式会在内存中形成 WebStream 造成较多的内存开销。关于该函数的具体优劣,开发者可以参考&a href=&/?target=http%3A///archives/ABTheory.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&你应该知道的AssetBundle管理机制&i class=&icon-external&&&/i&&/a&。&/p&&/blockquote&&p&&strong&Q15:项目在发布时,Player Setting中勾选的这个选项(Optimize Mesh Data),对于已经打包并且放到了Streaming Assets中的AssetBundle文件有效果吗?模型资源里有个Optimize Mesh,是否能达到同样的效果?&/strong&&/p&&blockquote&&p&理论上 Optimize Mesh Data 是 Build Player 或者 Bundle 时才生效的,所以之前打好的 Bundle 就没效果了。另外,两个选项的效果是不同的,后者是调整面片排序的。&/p&&/blockquote&&h2&&strong&二、资源使用&/strong&&/h2&&h2&&strong&纹理相关&/strong&&/h2&&p&&strong&Q1:关于贴图类型设置请问有什么好的建议呢?是否所有的贴图都设置为Advanced比较好?这种情况下的贴图内存是不是比较小?&/strong&&br&&img src=&/v2-10df2672eef5fa70d2cdb9_b.png& data-rawwidth=&629& data-rawheight=&637& class=&origin_image zh-lightbox-thumb& width=&629& data-original=&/v2-10df2672eef5fa70d2cdb9_r.png&&&/p&&blockquote&&p&Unity默认情况下会将绝大多数纹理设置为Texture模式。一般来说,Texture模式对于绝大多数纹理资源也都是合适的。上面的例子中,Advanced模式下之所以内存占用较小,是因为关闭了Mipmap选项,所以其内存下降了。其本质跟Advanced模式无关。Advanced模式较之Texture模式和其他模式,可以更大自由地对纹理资源进行控制。因此,如果你想对纹理资源进行更加自定义地设置,可以选择Advanced模式进行编辑。&/p&&/blockquote&&p&&strong&Q2:同样的包同一个图集,ETC2格式,在红米Note1上会比酷派的内存会大四倍,请问这是什么原因造成的?如果不支持OpenGL 3.0,会造成这么大的影响吗?&/strong&&/p&&blockquote&&p&ETC2 的格式理论上只在OpenGL ES 3.0 的设备上被支持,而在不被支持的设备上则会内部自动转成 RGBA32/ARGB32的格式,这对于 RGBA Compressed ETC2 8bits 的纹理就是放大了 4 倍。因此,如果希望在 OpenGL ES 2.0 的设备上对透明材质进行压缩,那么可以尝试使用分离 Alpha 通道的方式,用两个 ETC1 来进行压缩。&/p&&/blockquote&&p&&strong&Q3:我现在动态加载StreamingAssets下的贴图,代码如下&/strong&&br&&img src=&/v2-8d04f1006fcda1a8c75c38b37db97ec8_b.png& data-rawwidth=&581& data-rawheight=&59& class=&origin_image zh-lightbox-thumb& width=&581& data-original=&/v2-8d04f1006fcda1a8c75c38b37db97ec8_r.png&&&strong&我发现这种方式内存消耗很大,一张512 x 512的贴图占用了2MB,看官方的解析是内存和显存各需一份。想了解下动态加载贴图有什么推荐的方式吗?&/strong&&/p&&blockquote&&p&一般来说,我们比较建议通过AssetBundle来动态加载资源,而非通过bytes流来进行加载。如果你的项目正在使用这种方式来加载纹理,我们建议从策略上考虑将其更改。在我们目前来看,通过bytes流来生成资源,绝大部分原因是想对其进行加密,从而让资源难于破解。但其实这种加密方式用处不大,因为据我们所知,现在有很多工具可以直接通过底层显卡层来直接查看各种纹理、Mesh资源,比如Mali Graphics Debugger、Qualcomn Profiler等。因此,如果是从加密的角度来通过bytes流生成资源,那么我们建议通过AssetBundle这种直接的方式进行加载。&/p&&/blockquote&&p&&strong&Q4:iOS平台需要对图集做RGB和Alpha通道的分离吗?我发现在同样大小的图片(正方形),RGB Compressed PVRTC 4bits和RGBA Compressed PVRTC 4bits两种格式,占用内存是一样的,如果把一张图片分成两张,那么在iOS平台是不是占用内存多一倍?有透明通道的,对于它的图集怎么处理会更好一点?&/strong&&/p&&blockquote&&p&通常iOS下是不需要做通道分离的,因为 iOS 通用的 PVRTC 格式支持 Alpha 通道。但目前也有团队反馈,在 iOS 上进行通道分离有助于减少失真,可以在一定程度上提高视觉效果,因此也可以尝试做一个对比。&br&如果发现占用内存是一样的,那么原始图片是RGB的。如果iOS上做通道分离,内存确实会增加一倍。UI的纹理在iOS下可以直接选择默认的 Compress,在打Atlas时会自动处理成 PVRTC,开发团队可以从Sprite packer窗口来看Atlas的压缩格式做个确认。&/p&&/blockquote&&p&&strong&Q5:在Unity 4.x的版本中,所有UI贴图使用ETC2格式,即使目标设备不支持该格式,也会解压成RGBA32使用。 而在目前使用的Unity 5.3.4版本中,iOS平台无法设置ETC2格式。如果压缩只能使用PVRTC格式,那么PVRTC存在显示效果比较差,并且图片必须为正方形,但如果用RGBA32格式,贴图占用的内存和存储又都过大,请问目前版本的Unity在iOS平台上应该如何设置UI贴图的压缩格式?&/strong&&/p&&blockquote&&p&我们建议可以先尝试其他的压缩格式看是否可以达到类似的效果,如ASTC格式。ASTC 在 iOS 的高端机上是被支持的,因此理论上在 Editor 下不会强制把 ASTC 转为 RGBA32,建议尝试设置为 ASTC 后打包,从 Editor.log 中或者直接从包体大小上可以看出是否确实使用了 ASTC。&/p&&p&一般来说,如果 RGBA16 的效果可以接受的话,建议使用 RGBA16,虽然打包时相对大一些,但是内存中相比 RGBA32 能够减半,但使用 ASTC 的话,虽然打包时比较小,但是在普通机型上会被处理成 RGBA32,导致过大的内存开销。&/p&&/blockquote&&p&&strong&Q6:请问Unity引擎中使用什么贴图压缩格式,可以保证在占用内存相对较小的情况下True Color效果和原图相当?同时在iOS和Android平台上图片的压缩格式分别用什么比较合适?有什么需要注意的地方吗?&/strong&&/p&&blockquote&&p&目前来讲,并不存在一个所有GPU平台都支持硬件解压的压缩格式。 ETC1 和 PVRTC 分别是Android和iOS上我们最推荐的格式。 但对于透明纹理,ETC1不支持,而 PVRTC 则可能有较大失真,因此更推荐使用 RGBA 16。&br&一般来说建议直接使用 Unity 默认的压缩格式(即选择 Compressed 即可,不需要做特殊设置),Unity 会做如下处理:&/p&&ol&&li&Android 上不带Alpha通道的图片采用 ETC1,带Alpha通道的图片采用True Color中的RGB16,TrueColor中的 RGBA16 会&比 RGBA32 更节省空间,但图像的显示质量会差一些;&/li&&li&iOS 上使用 PVRTC,但PVRTC格式要求纹理的长宽相等,且都是2的幂次(即POT,在ImportSettings中可以将NPOT的纹理自动转换成POT)。&/li&&/ol&&p&另外,针对Android 上的带Alpha通道的图片,还有一种常见的做法,即把Alpha通道独立出来作为另一张纹理,从而将 RGB 部分和 Alpha 部分分别采用 ETC1来压缩,但渲染时就需要自定义的 Shader来处理。&br&同时,我们不建议直接使用 RGBA32 格式的纹理,因为它占用了很大的内存。一般建议使用 RGBA16 和 ETC 格式的纹理来进行加载。 如果转换到 RGBA16 格式时出现了类似“色阶”的颜色问题,则建议尽可能避免大量的过渡色使用。&/p&&/blockquote&&p&&strong&Q7:请问游戏中特效使用的很多贴图, 一般有什么好的方式去管理吗 ? 不合并图集的话会有上千张小的透明贴图, 合并图集又会有占用内存过多的问题。&/strong&&/p&&blockquote&&p&可以合并成Atlas,一般将尽可能同时出现频率较高的Texture合成Atlas,这样并不会造成内存过大。在这方面也可以参考我们前不久推荐的插件&a href=&/?target=http%3A///archives/Resource_Plugin.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Mesh Baker&i class=&icon-external&&&/i&&/a&。&/p&&/blockquote&&p&&strong&Q8:iOS上方形POT图片有时候会失真,请问这种情况如何避免?一张NPOT的图变换成POT,是否有推荐的方法? 采用 ToLarger 的模式拉成POT是否会有损失呢?&/strong&&/p&&blockquote&&p&在其他设置一致的情况下,这两种方式无论在加载还是渲染方面其实并没有实质上的差别。在我们接触到的大多数案例中,纹理资源方面的问题除了尺寸外,纹理格式、Mipmap设置和Read&Write功能同样是需要研发团队时刻关注的。&/p&&/blockquote&&p&&strong&Q9:纹理Atlas是建议合成一张2048(尺寸)的纹理还是四张1024的纹理?&/strong&&/p&&blockquote&&p&在其他设置一致的情况下,这两种方式无论在加载还是渲染方面其实并没有实质上的差别。在我们接触到的大多数案例中,纹理资源方面的问题除了尺寸外,纹理格式、Mipmap设置和Read&Write功能同样是需要研发团队时刻关注的。&/p&&/blockquote&&p&&strong&Q10:NGUI的图集在内存里存了多份,求问怎么清理?&/strong&&br&&img src=&/v2-c13d71dfcb_b.png& data-rawwidth=&263& data-rawheight=&260& class=&content_image& width=&263&&&/p&&blockquote&&p&游戏运行中,UI Mesh出现多份不同内存的情况,是正常的,因为随着UI widget使用的增加或减少,创建的UI Mesh是会随着变化的。同时,如果不同UIPanel中存在相同Atlas的Widgets,则也会出现上图中的情况。因此,建议大家遇到这种情况时,查看单帧中NGUI UI Mesh重名的是否有多份重名资源。如果存在,则说明相同Atlas中的资源被多个不同的UIPanel所使用,这种情况是需要尽可能避免的。&br&&img src=&/v2-8eb2d1139bc4eddeded1ad_b.jpg& data-rawwidth=&2842& data-rawheight=&1538& class=&origin_image zh-lightbox-thumb& width=&2842& data-original=&/v2-8eb2d1139bc4eddeded1ad_r.jpg&&&br&&/p&&/blockquote&&p&&strong&Q11:我在UWA报告中看到大量的n/a资源,其格式的高度和宽度等信息都无法获取,并且存在大量重复,请问我该如何定位这些文件?能否优化解决呢?&/strong&&/p&&blockquote&&p&&图中n/a资源是我们在项目运行时检测到的无名称资源,一般来说,该类型资源并非Asset文件夹中的美术资源,而是项目通过脚本动态生成的资源,比如new Mesh、new Texture等操作,即会生成这种类型的无名称资源。&br&对此,我们建议研发团队详细检测逻辑代码/第三方插件中诸如New Mesh/Textue等此类操作,同时,在脚本动态生成该类资源后,为其赋上一个名字,这样即可在后续测试中看到对应名称的资源使用情况。&&/p&&/blockquote&&h2&&strong&网格相关&/strong&&/h2&&p&&strong&Q1:如果一个模型对应Skinned Mesh Renderer实例,那其所占的内存会随着角色增加而增长么 ?&/strong&&/p&&blockquote&&p&简单地从一个角色Prefab实例化(Instantiate)出多个实例时,Mesh并不会出现多份(这个行为与其他资源是一致的,包括Texture,AnimationClip,Material等等)。如果在内存中发现多份,可以考虑从项目中AssetBundle的加载方式入手,因为即使是同一个AssetBundle中的同一个角色Prefab,如果被反复进行“加载-实例化-卸载”操作,依然是会导致Mesh出现多份的(当然其他的资源也是一样)。&/p&&/blockquote&&p&&strong&Q2:我有一个特效依赖了两个FBX。我把这两个FBX的这个勾选去掉,Editor运行正常。否则就会宕机,请问这是什么原因?&/strong&&br&&/p&&img src=&/v2-4d683f3e50f26c192e6a524acd3534ac_b.png& data-rawwidth=&332& data-rawheight=&33& class=&content_image& width=&332&&&blockquote&&p&将FBX上的Read/Write Enabled关闭后,内存中便不再保存其Mesh的副本(只存在显存中),因此其属性就不可再被访问和修改。而粒子系统通常需要动态地修改其粒子的顶点属性。因此,理论上来说,供粒子系统使用的Mesh是需要开启Read/Write Enabled的,而在Editor下Mesh和Texture都是强制开启的,所以在真机上就会出现问题。&/p&&/blockquote&&p&&strong&Q3:MeshBaker 烘焙的Mesh可以保存到Prefab中,但是不能像FBX一样,设置Model导入设置中的Generate Lightmap UVs 等信息,请问有没有大招可以处理此情况?&/strong&&/p&&blockquote&&p&首先从理论上说,一个 Mesh 只能有一个 LightmapIndex 和 LightmapOffset 属性,这就决定了 Mesh 的合并必须在 Lightmap 的烘焙之前。&br&而在做Mesh合并时,需要注意到UV2对于一个Mesh而言,其所有三角面的UV区域都必须是互不重叠的,所以不能简单直接地合并。&br&考虑到合并前每一个Mesh的UV2区域都应该是在[0,1]x[0,1]的区间中,在合并时可以给每一个UV2区域做一个缩小和平移,从而可以把每个区间在互不重叠的情况下,放到同一个[0,1]x[0,1]的区间中。&br&在UV2也正确拼合后,重新进行Lightmap的烘焙即可得到正确的效果。&/p&&/blockquote&&h2&&strong&动画片段相关&/strong&&/h2&&p&&strong&Q1:我想要在Editor下批量地对Animator Controller文件中每一个的State里的Animation Clip进行替换,但好像没有看到 Unity引擎有提供类似的API,只提供了能在Runtime时进行替换的方法,类似下图:&/strong&&br&&br&&img src=&/v2-c4fac515ea_b.png& data-rawwidth=&521& data-rawheight=&89& class=&origin_image zh-lightbox-thumb& width=&521& data-original=&/v2-c4fac515ea_r.png&&&br&&strong&我现在想要达到的目地是在Editor下写一个批量替换Animation Clip的插件,请问下Unity引擎是否有提供这样的接口呢?&/strong&&/p&&blockquote&&p&在Unity 5.x 中已有一套完整且稳定的 API 可以访问、修改和创建 Animator 中的任何元素。其命名空间是在 UnityEditor.Animations 下,以下Blog 中有一个简单的例子是通过脚本创建一个 AnimatorController 以及其中的各种属性和参数。&a href=&/?target=http%3A////shiny-new-animation-features-in-unity-5-0/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Shiny new animation features in Unity 5.0 – Unity Blog&i class=&icon-external&&&/i&&/a&&br&另外,如果需要修改Animation Clip,可以直接修改一个 AnimationState 的 Motion 属性。 Animation Clip可以继承自 Motion。&/p&&/blockquote&&p&&strong&Q2:如果我的Animator是直接引用了FBX里的动画文件,而不是复制了FBX的动画文件出来再引用,那么打包的时候会把FBX都打包吗?&/strong&&/p&&blockquote&&p&这种情况下并不会把 FBX 打入 AssetBundle 中。将动画文件Copy出来通常是为了直接对动画文件打包,作为依赖包。&/p&&/blockquote&&p&&strong&Q3:我们的动画是放在FBX文件里的&/strong&&/p&&p&&img src=&/v2-65d3c4b9c29e46714d22c_b.png& data-rawwidth=&425& data-rawheight=&426& class=&origin_image zh-lightbox-thumb& width=&425& data-original=&/v2-65d3c4b9c29e46714d22c_r.png&&&strong&这样做导致打包的时候把一些无用的文件也打进AssetBundle包里了,实际上我们只想使用最后这个动画文件。但在编辑器里选中FBX文件里的动画文件时却没有AssetLabels这个窗口,设置不了AssetBundle Name。&/strong&&br&&br&&img src=&/v2-366c88ec8cffce8b8e5924e_b.png& data-rawwidth=&328& data-rawheight=&80& class=&content_image& width=&328&&&br&&strong&是不是只能用代码设置?还是意味着不能设置AssetBundle Name,只能把动画文件提取出来,类似下图这样单独的一个文件?&/strong&&br&&/p&&img src=&/v2-43d7f4ad4bf60a05adf7_b.png& data-rawwidth=&337& data-rawheight=&41& class=&content_image& width=&337&&&blockquote&&p&在Unity 5.x 的打包机制下确实无法手动为 FBX 下的 Mesh 或 AnimationClip 单独资源设置 AssetBundle Name。因此,如果需要将这部分资源抽出来作为依赖包,目前确实就需要先通过脚本将这部分资源提取出来了。&/p&&/blockquote&&h2&&strong&音频相关&/s

我要回帖

更多关于 unity wrap mode 的文章

 

随机推荐