예제 #1
0
    /// <summary>
    /// 生成路径的递归函数
    /// </summary>
    /// <param name="lightningSegment">需要划分的线段</param>
    /// <param name="fractalTime">当前递归次数</param>
    /// <param name="maxFractalTime">最大递归次数</param>
    /// <param name="baseAttenuation">基础衰减</param>
    /// <param name="offsetRange">偏离值的范围</param>
    /// <param name="direction">闪电方向</param>
    /// <param name="forward">与闪电方向垂直的一个单位向量</param>
    /// <param name="right">与闪电方向垂直的一个单位向量</param>
    /// <param name="branchChance">生成分支的几率</param>
    private void GetFractcalLightning(LightningSegment lightningSegment, int fractalTime, int maxFractalTime, float baseAttenuation, Vector2 offsetRange, Vector3 direction, Vector3 forward, Vector3 right, float branchChance = 0f)
    {
        if (!lightningSegment.isLeaf() || fractalTime > maxFractalTime)
        {
            return;
        }
        float   zOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
        float   xOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
        Vector3 mid     = lightningSegment.Middle() + xOffset * right + zOffset * forward;

        lightningSegment.LeftChild          = new LightningSegment(lightningSegment.start, mid);
        lightningSegment.LeftChild.fractal  = fractalTime + 1;
        lightningSegment.LeftChild.uv       = lightningSegment.uv - LightningCreator.arrayForUV[lightningSegment.LeftChild.fractal];
        lightningSegment.RightChild         = new LightningSegment(mid, lightningSegment.end);
        lightningSegment.RightChild.fractal = fractalTime + 1;
        lightningSegment.RightChild.uv      = lightningSegment.uv + LightningCreator.arrayForUV[lightningSegment.RightChild.fractal];
        GetFractcalLightning(lightningSegment.LeftChild, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        GetFractcalLightning(lightningSegment.RightChild, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        if (Random.Range(0f, 1f) < branchChance)
        {
            //制作h形片段
            zOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            xOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            float   yOffset   = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            Vector3 branchEnd = lightningSegment.Middle() + xOffset * right + zOffset * forward + yOffset * direction;
            lightningSegment.Branch         = new LightningSegment(mid, branchEnd);
            lightningSegment.Branch.fractal = fractalTime + 1;
            lightningSegment.Branch.uv      = lightningSegment.uv + LightningCreator.arrayForUV[lightningSegment.Branch.fractal];
            GetFractcalLightning(lightningSegment.Branch, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        }
    }
예제 #2
0
 /// <summary>
 /// 填充Mesh的递归函数
 /// </summary>
 /// <param name="lightningSegment">需要生成Mesh的线段</param>
 /// <param name="vertices"></param>
 /// <param name="triangle"></param>
 /// <param name="uv"></param>
 /// <param name="obPos">摄像机位置</param>
 /// <param name="radius">当前的闪电粗细</param>
 /// <param name="attenuation">分支闪电的衰减程度</param>
 /// <param name="idx">顶点序号</param>
 private void SegmentToMesh(LightningSegment lightningSegment, List <Vector3> vertices, List <int> triangle,
                            List <Vector2> uv, Vector3 obPos, float radius, float attenuation, ref int idx)
 {
     if (lightningSegment.isLeaf())
     {
         Vector3 zMid    = lightningSegment.Middle();
         Vector3 zNormal = Vector3.Cross(zMid - obPos, lightningSegment.end - lightningSegment.start).normalized;
         var     finalR  = radius * attenuation;
         if (lightningSegment.Branch == null)
         {
             //Z型片段的Mesh生成
             vertices.Add(lightningSegment.start + finalR * zNormal);
             vertices.Add(lightningSegment.start - finalR * zNormal);
             vertices.Add(lightningSegment.end + finalR * zNormal);
             vertices.Add(lightningSegment.end - finalR * zNormal);
             triangle.Add(idx + 1);
             triangle.Add(idx);
             triangle.Add(idx + 2);
             triangle.Add(idx + 1);
             triangle.Add(idx + 2);
             triangle.Add(idx + 3);
             uv.Add(new Vector2(1, lightningSegment.uv));
             uv.Add(new Vector2(0, lightningSegment.uv));
             uv.Add(new Vector2(1, lightningSegment.uv));
             uv.Add(new Vector2(0, lightningSegment.uv));
             idx += 4;
         }
     }
     else
     {
         SegmentToMesh(lightningSegment.LeftChild, vertices, triangle, uv, obPos, radius, attenuation, ref idx);
         SegmentToMesh(lightningSegment.RightChild, vertices, triangle, uv, obPos, radius, attenuation, ref idx);
         if (lightningSegment.Branch != null)
         {
             SegmentToMesh(lightningSegment.Branch, vertices, triangle, uv, obPos, radius * attenuation, attenuation, ref idx);
         }
     }
 }