内容简介:【博物纳新】是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 语言高级编程》开源图书
- 开源不只是“喊喊” 看红帽的开源之道
- 中国开源走向世界,深圳落成国际开源谷
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pattern Recognition and Machine Learning
Christopher Bishop / Springer / 2007-10-1 / USD 94.95
The dramatic growth in practical applications for machine learning over the last ten years has been accompanied by many important developments in the underlying algorithms and techniques. For example,......一起来看看 《Pattern Recognition and Machine Learning》 这本书的介绍吧!