1. 程式人生 > >unity中用shader實現大海的特效

unity中用shader實現大海的特效

之前學過一個是做流水效果的

但是自我感覺效果不太好,波動太規律了,而且能看到上面的面像是由多個面組合成的,感覺有點假,不過功能是實現了。

using UnityEngine;
using System.Collections;

public class CreateWater : MonoBehaviour {

    Mesh mesh;

    public int tier = 10;//長度分段
    public int length = 10;//長
    public int width = 3;//寬
    public int hight = 10;//高

    private Vector3[] vs;//頂點座標
    private int[] ts;//頂點序列
    private Vector2[] newUVs;//UV貼圖
    private Vector3[] newNormals;//法線

    void Update()
    {
        int temp = ((tier + 1) * 8 + 4) * 3;//確定頂點數量

        vs = new Vector3[temp];
        ts = new int[temp];
        newUVs = new Vector2[temp];
        newNormals = new Vector3[temp];

        float dis = 2 * Mathf.PI / tier;//兩段只差的橫座標

        int count = 0;
        for (int i = 0; i < tier; i++)
        {
            float pos1 = i * length / tier - length / 2;
            float pos2 = (i + 1) * length / tier - length / 2;
            //頂面頂點座標
            vs[count] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), width);
            vs[count + 1] = new Vector3(pos2, Mathf.Sin(Time.time + (i + 1) * dis), -width);
            vs[count + 2] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), -width);

            vs[count + 3] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), width);
            vs[count + 4] = new Vector3(pos2, Mathf.Sin(Time.time + (i + 1) * dis), width);
            vs[count + 5] = new Vector3(pos2, Mathf.Sin(Time.time + (i + 1) * dis), -width);
            //頂面法線
            newNormals[count] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + i * dis), 0));
            newNormals[count + 1] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + (i + 1) * dis), 0));
            newNormals[count + 2] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + i * dis), 0));

            newNormals[count + 3] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + i * dis), 0));
            newNormals[count + 4] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + (i + 1) * dis), 0));
            newNormals[count + 5] = Vector3.Normalize(new Vector3(1, Mathf.Cos(Time.time + (i + 1) * dis), 0));

            //前面頂點座標
            vs[count + 6] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), -width);
            vs[count + 7] = new Vector3(pos2, -hight, -width);
            vs[count + 8] = new Vector3(pos1, -hight, -width);

            vs[count + 9] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), -width);
            vs[count + 10] = new Vector3(pos2, Mathf.Sin(Time.time + (i + 1) * dis), -width);
            vs[count + 11] = new Vector3(pos2, -hight, -width);
            //前面法線
            for (int j = 0; j < 6; j++)
            {
                newNormals[count + 6 + j] = Vector3.back;
            }
            //後面頂點座標
            vs[count + 12] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), width);
            vs[count + 13] = new Vector3(pos1, -hight, width);
            vs[count + 14] = new Vector3(pos2, -hight, width);

            vs[count + 15] = new Vector3(pos1, Mathf.Sin(Time.time + i * dis), width);
            vs[count + 16] = new Vector3(pos2, -hight, width);
            vs[count + 17] = new Vector3(pos2, Mathf.Sin(Time.time + (i + 1) * dis), width);
            //後面法線
            for (int j = 0; j < 6; j++)
            {
                newNormals[count + 12 + j] = Vector3.forward;
            }
            //下面頂點座標
            vs[count + 18] = new Vector3(pos1, -hight, width);
            vs[count + 19] = new Vector3(pos1, -hight, -width);
            vs[count + 20] = new Vector3(pos2, -hight, -width);

            vs[count + 21] = new Vector3(pos1, -hight, width);
            vs[count + 22] = new Vector3(pos2, -hight, -width);
            vs[count + 23] = new Vector3(pos2, -hight, width);
            //下面法線
            for (int j = 0; j < 6; j++)
            {
                newNormals[count + 18 + j] = Vector3.down;
            }

            count += 24;
        }

        //兩側頂點座標及法線
        vs[vs.Length - 12] = new Vector3(-length / 2, Mathf.Sin(Time.time), width);
        vs[vs.Length - 11] = new Vector3(-length / 2, -hight, -width);
        vs[vs.Length - 10] = new Vector3(-length / 2, -hight, width);

        vs[vs.Length - 9] = new Vector3(-length / 2, Mathf.Sin(Time.time), width);
        vs[vs.Length - 8] = new Vector3(-length / 2, Mathf.Sin(Time.time), -width);
        vs[vs.Length - 7] = new Vector3(-length / 2, -hight, -width);

        for (int j = 0; j < 6; j++)
        {
            newNormals[vs.Length - 12 + j] = Vector3.left;
        }

        vs[vs.Length - 6] = new Vector3(length / 2, Mathf.Sin(Time.time + tier * dis), width);
        vs[vs.Length - 5] = new Vector3(length / 2, -hight, width);
        vs[vs.Length - 4] = new Vector3(length / 2, -hight, -width);

        vs[vs.Length - 3] = new Vector3(length / 2, Mathf.Sin(Time.time + tier * dis), width);
        vs[vs.Length - 2] = new Vector3(length / 2, -hight, -width);
        vs[vs.Length - 1] = new Vector3(length / 2, Mathf.Sin(Time.time + tier * dis), -width);

        for (int j = 0; j < 6; j++)
        {
            newNormals[vs.Length - 6 + j] = Vector3.right;
        }

        for (int i = 0; i < ts.Length; i++)
        {   //頂點序列賦值
            ts[i] = i;
        }

        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;
        mesh.vertices = vs;
        mesh.uv = newUVs;
        mesh.triangles = ts;
        mesh.normals = newNormals;
    }

}

原文連結:http://blog.csdn.net/qq_18408937/article/details/44161229