2019-04-11

shader

Shader "Unlit/Ocean"
{
    Properties
    {
        _MainColor("MainColor",Color)=(0,0,1,1)
        _Smoothness("Smoothness",Range(0,1))=0.7
        _Metallic("Metallic",Range(0,1))=0
        _WaveFoamDir("Wave foam dirction",Vector)=(0,0,0,0)
        
        [Header(Distortions1)]
        _NormalMap("NormalMap1",2D)="bump"{}
        _NormalMapMoveDir("NormalMapMoveDir",vector)=(1,1,1,1)
        _NormalMapMoveSpeed("NormalMapMoveSpeed",float)=0
        _HeightMap("HeightMap",2D)="black"{}
        [Space(30)]

        [Header(Distortions2)]
        _NormalMap2("NormalMap2",2D)="bump"{}
        _NormalMapMoveDir2("NormalMapMoveDir2",vector)=(-1,1,1,1)
        _NormalMapMoveSpeed2("NormalMapMoveSpeed2",float)=0
        _HeightMap2("HeightMap",2D)="black"{}
        [Space(30)]

        [Header(Distortion Setting)]
        _NormalScale("NormalScale",Range(0,1))=0.6
        _HeightScale("HeightScale",Range(0,1))=1.0
        _HeightMapFoamScale("FoamScale",Range(0,5))=1.0
        _FoamSpread("FoamSpread",float)=1.0


        //-------Wave Set-------
            [Header(Base Wave)]
            _PointBumpScale("PointBumpScale",Range(0,1))=1
            [Toggle(ENABLE_BASEWAVE)]_baseWave("baseWave",float)=1
            _waveLength("waveLength",float)=5
            _amplitude("amplitude",float)=3
            _steepness("steepness",float)=1
            _dirX("dirX",Range(-1,1))=1
            _dirZ("dirZ",Range(-1,1))=1
            _speed("speed",float)=5
            _fadeSpeed("fadespeed",float)=1
            [space(20)]

            [Header(Wave1)]
            [Toggle(ENABLE_WAVE1)]_wave1("wave1",float)=1
            _waveLength1("waveLength",float)=5
            _amplitude1("amplitude",float)=3
            _steepness1("steepness",float)=1
            _dirX1("dirX",Range(-1,1))=1
            _dirZ1("dirZ",Range(-1,1))=1
            _speed1("speed",float)=5
            _fadeSpeed1("fadespeed",float)=1
            [space(20)]

            [Header(Wave2)]
            [Toggle(ENABLE_WAVE2)]_wave2("wave2",float)=1
            _waveLength2("waveLength",float)=5
            _amplitude2("amplitude",float)=3
            _steepness2("steepness",float)=1
            _dirX2("dirX",Range(-1,1))=1
            _dirZ2("dirZ",Range(-1,1))=1
            _speed2("speed",float)=5
            _fadeSpeed2("fadespeed",float)=1
            [space(20)]

            [Header(Wave3)]
            [Toggle(ENABLE_WAVE3)]_wave3("wave3",float)=1
            _waveLength3("waveLength",float)=5
            _amplitude3("amplitude",float)=3
            _steepness3("steepness",float)=1
            _dirX3("dirX",Range(-1,1))=1
            _dirZ3("dirZ",Range(-1,1))=1
            _speed3("speed",float)=5
            _fadeSpeed3("fadespeed",float)=1
            [space(20)]

            [Header(Wave4)]
            [Toggle(ENABLE_WAVE4)]_wave4("wave4",float)=1
            _waveLength4("waveLength",float)=5
            _amplitude4("amplitude",float)=3
            _steepness4("steepness",float)=1
            _dirX4("dirX",Range(-1,1))=1
            _dirZ4("dirZ",Range(-1,1))=1
            _speed4("speed",float)=5
            _fadeSpeed4("fadespeed",float)=1
        //
    }
    SubShader
    {
        //-------pass 1---------
        ZWrite on 
        Cull back 
        Colormask 0
        Lighting off 
        CGPROGRAM
        
        #pragma surface surf Standard vertex:vert nometa
        #include "UnityCG.cginc"
        #include "WaterIncludes2.cginc"
        #pragma shader_feature ENABLE_BASEWAVE
        #pragma shader_feature ENABLE_WAVE1
        #pragma shader_feature ENABLE_WAVE2
        #pragma shader_feature ENABLE_WAVE3
        #pragma shader_feature ENABLE_WAVE4

        struct Input{
            float2 uv_MainTex;
        };
        //NormalMap1
        float4 _NormalMapMoveDir;
        float _NormalMapMoveSpeed;
        sampler2D _HeightMap;
        //Normalmap2
        float4 _NormalMapMoveDir2;
        float _NormalMapMoveSpeed2;
        sampler2D _HeightMap2;
        //Normal set
        float _HeightScale;

        //Wave set
        float _PointBumpScale;

        void vert(inout appdata_full v){
            //position
            float4 worldPos=mul(unity_ObjectToWorld,v.vertex);
            float4 worldPos1=GetWaveOffset(worldPos);
    
            //------heightMap-------------
            float height1=tex2Dlod(_HeightMap,float4(v.texcoord.xy+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x,0,0)).r;
            height1=(height1-1)*2;
            float height2=tex2Dlod(_HeightMap2,float4(v.texcoord.xy+_NormalMapMoveDir2.xy*_NormalMapMoveSpeed2*_Time.x,0,0)).r;
            height2=(height2-0.5)*2;
            worldPos1.y+= (height1+height2)*_HeightScale;
            worldPos1.y=lerp(0,worldPos1.y,_PointBumpScale);
            
            //output to Object Data
            v.vertex=mul(unity_WorldToObject,float4(worldPos1.xyz,1.0));
        }

        void surf(Input IN, inout SurfaceOutputStandard o) {}


        ENDCG

        //------end pass---------
        GrabPass{"_WaterBackground"}

        //------pass 2 -----------
        Tags { "RenderType"="Transparent""Queue"="Transparent" }
        ZWrite off  
        Cull back 
        Blend SrcAlpha OneMinusSrcAlpha
        Colormask RGBA 

        CGPROGRAM

        #pragma surface surf Standard vertex:vert alpha:fade nometa novertexlights noforwardadd 
        #include"UnityCG.cginc"
        #include "UnityPBSLighting.cginc"
        #include"WaterIncludes2.cginc"
        #pragma target 3.0
        #pragma shader_feature ENABLE_BASEWAVE
        #pragma shader_feature ENABLE_WAVE1
        #pragma shader_feature ENABLE_WAVE2
        #pragma shader_feature ENABLE_WAVE3
        #pragma shader_feature ENABLE_WAVE4

        struct Input {
            float2 uv_MainTex;
            float2 uv_NormalMap;
            float2 uv_NormalMap2;
            float worldDirNormal;
            float crestFactor;
        };
        //Base Set
        float4 _MainColor;
        float _Metallic;
        float _Smoothness;
        float3 _WaveFoamDir;


        //NormalMap1
        sampler2D _NormalMap;
        float4 _NormalMapMoveDir;
        float _NormalMapMoveSpeed;
        sampler2D _HeightMap;
        //Normalmap2
        sampler2D _NormalMap2;
        float4 _NormalMapMoveDir2;
        float _NormalMapMoveSpeed2;
        sampler2D _HeightMap2;
        //Normal set
        float _NormalScale;
        float _HeightScale;
        float _HeightMapFoamScale;

        //Wave set
        float _PointBumpScale;

        void vert(inout appdata_full v,out Input o){
            UNITY_INITIALIZE_OUTPUT(Input,o);
            //position
            float4 worldPos=mul(unity_ObjectToWorld,v.vertex);
            float4 worldPos1=GetWaveOffset(worldPos);
            o.crestFactor=worldPos1.w;
            //--------heightMap--------
            float height1=tex2Dlod(_HeightMap,float4(v.texcoord.xy+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x,0,0)).r;
            height1=(height1-1)*2;
            float height2=tex2Dlod(_HeightMap2,float4(v.texcoord.xy+_NormalMapMoveDir2.xy*_NormalMapMoveSpeed2*_Time.x,0,0)).r;
            height2=(height2-0.5)*2;
            worldPos1.y+= (height1+height2)*_HeightScale;

            worldPos1.y=lerp(0,worldPos1.y,_PointBumpScale);
            worldPos1.y+= 0.01;

            o.worldDirNormal=normalize(GetNormalNum(worldPos).xyz);
            
            //output to Object Data
            v.vertex=mul(unity_WorldToObject,float4(worldPos1.xyz,1.0));
            v.normal=normalize(GetNormalNum(worldPos)) ;
        }

        void surf(Input IN, inout SurfaceOutputStandard o) {
            float noFoam= saturate(dot(IN.worldDirNormal,normalize(_WaveFoamDir)));
            
            //--------NormalMap---------------
            float3 normal=UnpackScaleNormal(tex2D(_NormalMap,IN.uv_NormalMap+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x),_NormalScale);
            float3 normal2=UnpackScaleNormal(tex2D(_NormalMap2,IN.uv_NormalMap2+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x),_NormalScale);
            float3 totalNormal=normalize(float3(normal.xy+normal2.xy,normal.z*normal2.z));

            //--------Height map foam---------
            float heightMapAdd1=pow(tex2D(_HeightMap,IN.uv_NormalMap+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x).r,4);
            float heightMapAdd2=pow(tex2D(_HeightMap2,IN.uv_NormalMap2+_NormalMapMoveDir.xy*_NormalMapMoveSpeed*_Time.x).r,4);
            float totalHeightAdd=((heightMapAdd1+heightMapAdd2)/2)*_HeightScale*_HeightMapFoamScale;

            //---------Total water foam-------
            float3 foam= ((totalHeightAdd+IN.crestFactor)/2)*(1-noFoam);

            o.Albedo=_MainColor+foam;
            o.Alpha= saturate(_MainColor.w+foam.r);
            o.Normal=totalNormal;
            o.Metallic=_Metallic;
            o.Smoothness=saturate(_Smoothness-foam);
        }

        ENDCG
    }
}

#if !defined(WATER_INCLUDED)
    #define WATER_INCLUDED

#define PI 3.14

//--------------Wave Data-------------------------
    float _FoamSpread;

    #if ENABLE_BASEWAVE
    float _waveLength;
    float _amplitude;
    float _steepness;
    float _dirX;
    float _dirZ;
    float _speed;
    float _fadeSpeed;
    #endif

    #if ENABLE_WAVE1
    float _waveLength1;
    float _amplitude1;
    float _steepness1;
    float _dirX1;
    float _dirZ1;
    float _speed1;
    float _fadeSpeed1;
    #endif

    #if ENABLE_WAVE2
    float _waveLength2;
    float _amplitude2;
    float _steepness2;
    float _dirX2;
    float _dirZ2;
    float _speed2;
    float _fadeSpeed2;
    #endif

    #if ENABLE_WAVE3
    float _waveLength3;
    float _amplitude3;
    float _steepness3;
    float _dirX3;
    float _dirZ3;
    float _speed3;
    float _fadeSpeed3;
    #endif

    #if ENABLE_WAVE4
    float _waveLength4;
    float _amplitude4;
    float _steepness4;
    float _dirX4;
    float _dirZ4;
    float _speed4;
    float _fadeSpeed4;
    #endif

//---------------Genter Wave-------
    float4 WavePointOffset(float3 worldPos,float waveLength,float amplitude,float steepness,float dirX,float dirZ ,float speed ,float fadeSpeed){
        float3 offset;
        float frequency=2*PI/waveLength;
        float dirDotPos = dot(worldPos.xz,normalize(float2(dirX,dirZ)) );
        float phaseConstantSpeed=speed*frequency; 
        float fi= _Time.x*phaseConstantSpeed; //一帧的相位

        float fade = cos(fadeSpeed*_Time.x)/2+0.5;
        amplitude*=fade;

        offset.x = steepness*amplitude*dirX * cos(frequency*dirDotPos + fi);
        offset.y = amplitude*sin(frequency*dirDotPos+fi);
        offset.z = steepness*amplitude*dirZ * cos(frequency*dirDotPos + fi);

        //后面应用齐次除法
        float creatFactor=sin(frequency*dirDotPos+fi)*saturate(steepness)*fade;

        return float4(offset,creatFactor);
    }

    float3 WaveNormal(float3 worldPos,float amplitude,float steepness,float dirX,float dirZ,float waveLength,float speed ){
        float frequency =2*PI/waveLength;
        float phaseConstantSpeed=speed*2*PI/waveLength;
        
        float fi=_Time.x*phaseConstantSpeed;
        float dirDotPos=dot(normalize(float2(dirX,dirZ)),worldPos.xz);

        float WA=frequency*amplitude;
        float S=sin(frequency*dirDotPos+fi);
        float C=cos(frequency*dirDotPos+fi);

        float3 normal=float3(normalize(float2(dirX,dirZ)).x * WA * C,
                            min( 0.2f , steepness * WA * S),
                            normalize(float2(dirX,dirZ)).y * WA * C
        );
        
        return normal;
    }

    float4 GetWaveOffset(float4 worldPos){
        worldPos.w=0;
        float totSteepness=0.001;
        #if ENABLE_BASEWAVE
        worldPos+=WavePointOffset(worldPos,_waveLength,_amplitude,_steepness,_dirX,_dirZ,_speed,_fadeSpeed);
        totSteepness+=_FoamSpread;
        #endif
        #if ENABLE_WAVE1
        worldPos+=WavePointOffset(worldPos,_waveLength1,_amplitude1,_steepness1,_dirX1,_dirZ1,_speed1,_fadeSpeed1);
        totSteepness+=_FoamSpread;
        #endif
        #if ENABLE_WAVE2
        worldPos+=WavePointOffset(worldPos,_waveLength2,_amplitude2,_steepness2,_dirX2,_dirZ2,_speed2,_fadeSpeed2);
        totSteepness+=_FoamSpread;
        #endif
        #if ENABLE_WAVE3
        worldPos+=WavePointOffset(worldPos,_waveLength3,_amplitude3,_steepness3,_dirX3,_dirZ3,_speed3,_fadeSpeed3);
        totSteepness+=_FoamSpread;
        #endif
        #if ENABLE_WAVE4
        worldPos+=WavePointOffset(worldPos,_waveLength4,_amplitude4,_steepness4,_dirX4,_dirZ4,_speed4,_fadeSpeed4);
        totSteepness+=_FoamSpread;
        #endif
        worldPos.w/=totSteepness;   
        return worldPos;
    }

    float3 GetNormalNum(float4 worldPos){
        //normal
        float3 normal=float3(0,0,0);
        #if ENABLE_BASEWAVE
        normal=WaveNormal(worldPos.xyz,_amplitude,_steepness,_dirX,_dirZ,_waveLength,_speed);
        #endif
        #if ENABLE_WAVE1
        normal+=WaveNormal(worldPos.xyz,_amplitude1,_steepness1,_dirX1,_dirZ1,_waveLength1,_speed1);
        #endif
        #if ENABLE_wAVE2
        normal+=WaveNormal(worldPos.xyz,_amplitude2,_steepness2,_dirX2,_dirZ2,_waveLength2,_speed2);
        #endif
        #if ENABLE_WAVE3
        normal+=WaveNormal(worldPos.xyz,_amplitude3,_steepness3,_dirX3,_dirZ3,_waveLength3,_speed3);
        #endif
        #if ENABLE_WAVE4
        normal+=WaveNormal(worldPos.xyz,_amplitude4,_steepness4,_dirX4,_dirZ4,_waveLength4,_speed4);
        #endif

        return float3(-normal.x,1-normal.y,-normal.z);
    }




#endif
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#region Editor

#if UNITY_EDITOR
using UnityEditor;

[CustomEditor(typeof(Builder))]
public class BuilderEditor:Editor
{
    public override void OnInspectorGUI()
    {
        Builder builder=(Builder)target;

        EditorGUI.BeginChangeCheck();

        //显示public 数据
        base.OnInspectorGUI();

        //当变动的时候更新
        if(EditorGUI.EndChangeCheck()){
            builder.UpdateMesh();
            Debug.Log("Updata Mesh!");
        }
    }
}

#endif

#endregion

[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Builder : MonoBehaviour
{
    [SerializeField]
    private MeshFilter _meshFilter;
    [SerializeField]
    public MeshRenderer _meshRenderer;

    [SerializeField]
    private Vector2 _cellSize=new Vector2(1,1);

    [SerializeField]
    private Vector2Int _gridSize =new Vector2Int(2,2);

    public MeshRenderer MeshRenderer{
        get{
            return _meshRenderer;
        }
    }

    public MeshFilter MeshFilter{
        get{
            return _meshFilter;
        }
    }

    private void Awake() {
        _meshFilter=GetComponent();
        _meshRenderer=GetComponent();
        UpdateMesh();
        //更新模型
    }

    public void UpdateMesh(){
        //target
        Mesh mesh =new Mesh();
        //data
        Vector2 size= new Vector2(0,0);
        size.x=_cellSize.x*_gridSize.x;
        size.y=_cellSize.y*_gridSize.y;

        Vector2 halfSize= size/2.0f;

        //obj
        List vertices=new List();
        List uvs=new List();
        //data
        Vector3 vertice=Vector3.zero;
        Vector2 uv=Vector2.zero;

        for(int iy=0;iy<_gridSize.y+1;iy++){
            vertice.z= iy*_cellSize.y -halfSize.y;
            uv.y= iy*_cellSize.y/size.y;

            for(int ix=0;ix<_gridSize.x+1;ix++){
                vertice.x=ix*_cellSize.x-halfSize.x;
                uv.x=ix*_cellSize.x/size.x;

                vertices.Add(vertice);
                uvs.Add(uv);
            }
        }

        int a=0;
        int b=0;
        int c=0;
        int d=0;

        //target
        int[] indexs=new int[_gridSize.x*_gridSize.y*2*3];
        int startIndex=0;
        for(int iy=0;iy<_gridSize.y;iy++){
            for(int ix=0;ix<_gridSize.x;ix++){
                a = iy*(_gridSize.x+1)+ix;
                b = (iy+1)*(_gridSize.x+1)+ix;
                c = b+1;
                d = a+1;

                startIndex = iy*(_gridSize.x*2*3) + ix*2*3;

                indexs[startIndex]=a;
                indexs[startIndex+1]=b;
                indexs[startIndex+2]=c;

                indexs[startIndex+3]=a;
                indexs[startIndex+4]=c;
                indexs[startIndex+5]=d;
            }
        }

        mesh.SetVertices(vertices);
        mesh.SetUVs(0,uvs);
        mesh.SetIndices(indexs,MeshTopology.Triangles,0);
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
        mesh.RecalculateTangents();

        _meshFilter.mesh=mesh;

    }

    #if UNITY_EDITOR

        private void OnValidate()
        {
            if (null == _meshFilter)
            {
                _meshFilter = GetComponent();
            }
            if (null == _meshRenderer)
            {
                _meshRenderer = GetComponent();
                if (null == _meshRenderer.sharedMaterial)
                {
                    _meshRenderer.sharedMaterial = new Material(Shader.Find("Standard"));
                }
            }
        }

    #endif


}

你可能感兴趣的:(2019-04-11)