内容简介:【博物纳新】是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。更多精彩内容请关注:lab.uwa4d.com导读
【博物纳新】是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。
更多精彩内容请关注:lab.uwa4d.com
导读
GrassBending是一个实现了草地交互弯曲效果的开源项目。该项目中,提供了一个用于替换低矮植被(hua hua cao cao)的Shader,和用于传递数据的相关脚本。本文将简单介绍该项目的使用、实现,并展示在不同机型上的性能数据。
项目信息
Unity版本:2018.3+
https://lab.uwa4d.com/lab/5c29315472745c25a802d1a7效果展示
使用方法
此项目中,提供了一个SampleScene,展示了如何使用这些脚本和Shader实现草地交互效果,即上文中效果展示的场景。在示例场景中,植被使用Unity Terrian制作,并且已经包含了6种不同的Details预设,并且它们的Billboard选项都是开启的。在示例场景中,作者提供的Shader为 "Hidden/TerrainEngine/Details/BillboardWavingDoublePass" ,可以直接应用到Billboard类型的Terrian Details上的。
对于角色或其他希望与草地相互作用的物体,您需要在其上挂载一个BendGrassWhenEnabled或BendGrassWhenVisible组件,用来标记交互关系。显然,这些脚本会在其所在上GameObject状态发生改变时,启用对应的检查,并将数据传递到草地的Shader中。
以BendGrassWhenEnabled为例,其上有两个参数。BendRadius用于控制物体影响草的球体范围大小。Priority则用来控制弯曲源的优先级,以防有超过上限的角色(或物体)同时影响到草地的弯曲,数字越小优先级越高。下图为调节Bend Radius造成的效果区别:
实现原理
本项目中,使用的是在Shader中改变顶点位置从而达到弯曲效果的方法。这种方法也是一个比较常见于手游项目的方法。
在添加了BendGrassWhenEnabled或BendGrassWhenVisible组件后,这些物体会在OnEnable/OnBecameVisible时会被添加为一个bender,再将所有benders的Position、BendRadius数据作为bendData传递给Shader。
1Shader.SetGlobalVectorArray(Shader.PropertyToID("_BendData"), bendData);
Shader拿到这些数据后,计算出顶点与bender的距离,并与BenderRadius进行比较,计算出顶点受的弯曲力大小bendPower和弯曲方向bendDir,并根据顶点色的alpha值,进行顶点位置的偏移,相关代码如下:
1float bendRadius = _BendData[i].w; 2//角色位置 3float3 benderWorldPos = _BendData[i].xyz; 4//顶点位置 5float3 vertexWorldPos = mul(unity_ObjectToWorld, v.vertex); 6 7//角色和顶点距离 8float distToBender = distance(float3(vertexWorldPos.x, 0, vertexWorldPos.z), float3(benderWorldPos.x, 0, benderWorldPos.z)); 9//顶点受到的弯曲力 10float bendPower = (bendRadius - min(bendRadius, distToBender)) / (bendRadius + 0.001); 11//弯曲方向 12float3 bendDir = normalize(vertexWorldPos - benderWorldPos); 13//顶点偏移量 14float2 vertexOffset = bendDir.xz * bendPower * v.texcoord.y * v.tangent.y; 15//根据顶点色的alpha值计算该顶点是否需要进行偏移 16v.vertex.xz += lerp(float2(0, 0), vertexOffset, saturate(bendRadius * v.color.w));
通过Wireframe视图可以更明显地看出这一步实现的效果,注意看角色走过时网格发生的变化:
在草地的绘制上,Shader通过两个Pass分别绘制了不透明和半透明边缘(Alpha Blend)的部分。也因此,在渲染的性能效率上会比较低,在使用时可以根据项目的实际情况进行调整。
性能测试
从上述的介绍可知,在这个项目中,使用Shader中偏移顶点的方式,可以将主要计算工作放在了GPU端,减轻CPU端的性能压力。
对此,我们在【红米4X】、【Vivo Y85】、【小米8】这三款不同档次的机型上进行了性能测试,测试版本开启了多线程渲染。最终得到了如下数据:
以红米4X为例,具体查看一下其中逻辑代码的耗时情况。从这里看到逻辑代码的耗时主要集中在Gfx.WaitForPresent和Camera.Render两个函数上,由此再具体查看两个函数的耗时曲线。
(红米4X的逻辑代码耗时Top10函数列表,此处统计数据包含了所有线程的耗时情况)
(Gfx.WaitForPresent&Camera.Render函数耗时曲线)
在耗时曲线中,波动比较明显。耗时波动受视野内渲染的草量影响,如上图所示,渲染草量多时(红框区域),耗时也会有明显上涨的峰值波段,渲染草量少时(绿框区域),耗时明显偏低。
综合以上数据,可以看到Gfx.WaitForPresent有超过30ms的耗时。
首先我们来复习一下这个函数的意义: 【扒一扒Profiler中的占坑鬼】 ,由此推测这里主要的性能瓶颈在GPU端,结合上文的分析,认为和Overdraw的关系比较大。对应Camera.Render的高值推测也是受GPU端压力造成的等待同步时间。
总结
使用Shader中偏移顶点的方式来实现草的交互效果也是一种常见可借鉴的思路。在移动端中更常见的是使用Mesh而非Terrian实现草地,并结合分块LOD处理分级效果。对于需要在移动端上实现上述效果的项目,建议参考此项目的实现思路,进行改进和优化后使用。
快用 UWA Lab合辑 Mark好项目!
今天的推荐就到这儿啦,或者它可直接使用,或者它需要您的润色,或者它启发了您的思路......
请不要吝啬您的 点赞和转发 ,让我们知道我们在做对的事。当然如果您可以留言给出宝贵的意见,我们会越做越好。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 聆听中国开源最强音 | 国内大厂开源项目齐聚 OSCAR 开源先锋日
- 小米 9 开源内核代码,上市即开源
- 开源 | 陌陌风控系统正式开源
- 开源 |《Go 语言高级编程》开源图书
- 开源不只是“喊喊” 看红帽的开源之道
- 中国开源走向世界,深圳落成国际开源谷
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Handbook of Data Structures and Applications
Dinesh P. Mehta / Chapman and Hall/CRC / 2004-10-28 / USD 135.95
In the late sixties, Donald Knuth, winner of the 1974Turing Award, published his landmark book The Art of Computer Programming: Fundamental Algorithms. This book brought to- gether a body of kno......一起来看看 《Handbook of Data Structures and Applications》 这本书的介绍吧!