• Unity3D手游开发日记(5)


    一直在思考怎么让场景更有生机,我觉得植被的随风摆动是必不可少的.CE3引擎的植被bending就做得特别棒.我也准备在手机上做一套.

    先分析一下植被摆动常见的几种做法.其实不管哪种做法,核心就是让植被顶点做动画,有的顶点动的少(比如树根),有的顶点动的多(比如树顶),根据怎么样的权重来动?

    方案1:  用UV来做权重.

    这种方案对UV展开有要求,要从0到1,只适合面片草,这样的话草的根部和顶部的摆动权重就是一个0到1的线性的变化,随便用一个正玄波就能实现简单摆动了,

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. // 根据UV实现简单的顶点动画  
    2. float4 newPos = v.vertex;   
    3. newPos.xyz += _Wind_Simple.xyz * v.texcoord.y * _BendingFactor;  



    方案2: 用顶点和模型原点的距离来做权重.

     CE3的Main Bending就是这种方案.顶点到模型原点的距离,其实就是模型的顶点值,再用这个值除以包围盒的参数,就能得到每个顶点0到1的摆动权重,很简单是吧,这种方案对UV就没要求,适合所有植被,但是,这种方案不能用于合批,比如Unity自带的静态合批,因为合批以后,模型其实已经变了,顶点到原点的距离也已经变了.

    方案3:用顶点颜色来做权重

    CE3的Detail Bending就是此方案.让美术刷顶点颜色,来作为摆动权重,顶点颜色有几个通道,每个通道实现一种频率的摆动,这样就可以实现比较复杂的摆动,比如Blue通道用来处理主干的摆动,Red通道处理树枝的摆动,Green通道用来处理树叶的细节抖动.这种方案好处是,不受UV和合批的影响,适合任何植被,而且还可以实现比较复杂的细节抖动,让抖动更真实.麻烦的就是要教会美术刷顶点色,而且效率开销最大.

    此方案应该是最完美的植被摆动方案,GPU GEM3对此有详细分析:

    点击打开链接

    结合项目实际情况,我的整体方案如下:

    1.草用第一种,效率比较高

    2.树木和旗子用第三种,控制使用,而且尽量减少这种模型的顶点数量,

    全局风控制,

    摆动的幅度还应该受风影响:

    草的话用一种风,树木的话单独用一种风.

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
      1. [ExecuteInEditMode]   
      2. public class VegetationWind : MonoBehaviour  
      3. {  
      4.     public Vector4 Wind = new Vector4(0.85f, 0.075f, 0.4f, 0.5f);  
      5.     public float WindFrequency = 0.75f;  
      6.   
      7.     private float WaveFrequency = 4.0f;  
      8.     private float WaveAmplitude = 0.1f;  
      9.   
      10.     void Start()  
      11.     {  
      12.         Shader.SetGlobalVector("_Wind_VertexColor", Wind);  
      13.         Shader.SetGlobalVector("_Wind_Simple", Wind);  
      14.     }  
      15.   
      16.     void Update()  
      17.     {  
      18.         // wind 1  
      19.         Vector4 Wind1 = Wind * ((Mathf.Sin(Time.realtimeSinceStartup * WindFrequency)));  
      20.         Wind1.w = Wind.w;  
      21.   
      22.         // wind 2q  
      23.         //Vector4 Wind2 = Wind1 * Wind1.w;  
      24.         Vector4 Wind2 = new Vector4();  
      25.         Wind2.x += Mathf.Sin(Time.realtimeSinceStartup * WaveFrequency) * WaveAmplitude;  
      26.         Wind2.y = 0;  
      27.         Wind2.z += Mathf.Sin(Time.realtimeSinceStartup * WaveFrequency + Mathf.PI * 0.5f) * WaveAmplitude;  
      28.         Wind2.w = 0;  
      29.   
      30.         Shader.SetGlobalVector("_Wind_VertexColor", Wind1);  
      31.         Shader.SetGlobalVector("_Wind_Simple", Wind2);  
      32.     }  
      33. }  
  • 相关阅读:
    STL之list函数详解
    深入剖析deque容器实现
    STL之deque详解
    STL之vector函数详解
    关于vector大小(size)和容量(capacity)总结
    typename 与 typedef的区别与应用
    oracle解除锁表【原】
    Spring触发器触发2次问题【转】
    JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮【转】
    使用JavaScript修改浏览器URL地址栏的实现代码【转】
  • 原文地址:https://www.cnblogs.com/czaoth/p/5785635.html
Copyright © 2020-2023  润新知