简单水unity urp

Shader "Ocean/OceanShader"
{
    Properties
    {
        [IntRange]_WaveCount("海浪数量",Range(1,6))=0
        _LightDir("光照方向",vector)=(1,1,1,1)
        _AvgSwell("海浪平局高度",Range(0,10))=0.5
        _AvgWaveLength("海浪的波长",Range(0,10))=2.9
        _WindDirection("海浪方向",Range(-180,180))=-177
        _WindSpeed("WindSpeed",float)=0.1
        _Metallic("金属度", Range(0,1)) = 1
        _Roughness("粗糙度", Range(0,1)) = 1
      
        [HDR]_Color("Color",Color)=(1,1,1,1)
        _SurfaceMap("海浪法线",2D)="bump"{}
        _BumpScale("海浪法线强度",Range(0,2))=0.25
        _FoamMap("FomMap",2D)="bump"{}
        _MaxWaveHeight("海浪显示的高度范围",Range(0.1,1))=1
        _AdjustFoam("海浪范围",Range(0,3))=0.5
        [Toggle(_OPENADJUST_ON)]_OpenACES("矫正",int)=0
        _PostColor("PostcAdjust",float)=1
        [Toggle(_CUSTOMREFLECT_ON)]_CustomReflectON("自定义环境球",int)=0
        _ReflectCube("环境球",Cube)="gray"{}
        
    }
 
    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" }
        LOD 100
 
        Pass
        {
            Name "Unlit"
            Tags{"LightMode" = "UniversalForward"}
            Blend SrcAlpha OneMinusSrcAlpha
            Cull Back
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define kDirSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04)
         
         
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #pragma shader_feature_local _CUSTOMREFLECT_ON
            #pragma shader_feature_local   _OPENADJUST_ON
 
 
            struct Attributes
            {
                float4 positionOS       : POSITION;
                float2 uv               : TEXCOORD0;
                
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
 
            struct Varyings
            {
                float4 positionCS       : SV_POSITION;
             
                float2 texcoord         : TEXCOORD0;
                float3 normalWS         : TEXCOORD1;
                float4 texcoord1        : TEXCOORD2;
                float3 posWS            : TEXCOORD3;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct WaveStruct
            {
	            float3 position;
	            float3 normal;
            };
            struct Wave
            {
	            half amplitude;
	            half direction;
	            half wavelength;
	            half2 origin;
	            half omni;
                int _WaveCount;
            };
             CBUFFER_START(UnityPerMaterial)
              
                half _WaveCount;
                half _WindDirection;
                half _AvgSwell;
                half _AvgWaveLength;
                half _WindSpeed;
                half4 _Color;
                half _BumpScale;
                half _Metallic;
                float _Roughness;
                float _PostColor;
                float _MaxWaveHeight;
                half _AdjustFoam;
                half4 _ReflectCube_HDR;
                half3 _LightDir;
                static half3 randomSeedList[6]=
                {
                    half3(0.5589265,88.53946f,0.6121008f),
                    half3(0.668604f,-87.46983f,0.8987388f),
                    half3(0.6767546f,-71.35088f,0.6283937f),
                    half3(1.05889f,42.03598f,1.174131f),
                    half3(1.012532f,-47.16227f,1.543352f),
                    half3(1.54227f,-3.399506f,1.147515f)
                };
             Wave _Wave[6];
             CBUFFER_END
          
            TEXTURE2D(_SurfaceMap);SAMPLER(sampler_SurfaceMap);
            TEXTURE2D(_FoamMap);SAMPLER(sampler_FoamMap);
            TEXTURECUBE(_ReflectCube);      SAMPLER(sampler_ReflectCube);
            float2 random(float2 st){
                st = float2( dot(st,float2(127.1,311.7)), dot(st,float2(269.5,183.3)) );
                return -1.0 + 2.0 * frac(sin(st) * 43758.5453123);
            }
            float Random(float n,float factor = 10000){
                   return frac(sin(n)*factor)*frac(cos(n)*factor);
            }

            float noise (float2 st) {
                float2 i = floor(st);
                float2 f = frac(st);
                float2 u = f*f*(3.0-2.0*f);
                return lerp( lerp( dot( random(i), f),
                                 dot( random(i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),
                            lerp( dot( random(i + float2(0.0,1.0) ), f - float2(0.0,1.0) ),
                                 dot( random(i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);
            }
          float3 ACESFilm(float3 LinearColor, float a, float b, float c, float d, float e)
         {
            const float ExposureMultiplier = _PostColor;                  // 曝光值

            const float3x3 PRE_TONEMAPPING_TRANSFORM =              // 色调映射矩阵
            {
             0.575961650, 0.344143820, 0.079952030,
             0.070806820, 0.827392350, 0.101774690,
             0.028035252, 0.131523770, 0.840242300
            };

            const float3x3 EXPOSED_PRE_TONEMAPPING_TRANSFORM = ExposureMultiplier * PRE_TONEMAPPING_TRANSFORM;    // key  场景颜色乘 曝光度 整个场景的色调。

            const float3x3 POST_TONEMAPPING_TRANSFORM =
            {
                1.666954300, -0.601741150, -0.065202855,
                -0.106835220, 1.237778600, -0.130948950,
                -0.004142626, -0.087411870, 1.091555000
            };

            float3 Color = mul(EXPOSED_PRE_TONEMAPPING_TRANSFORM, LinearColor);                        // 线性颜色转换
            Color = saturate((Color * (a * Color + b)) / (Color * (c * Color + d) + e));               // 应用到ACES 颜色校正

            return clamp(mul(POST_TONEMAPPING_TRANSFORM, Color), 0.0f, 1.0f);                          // 后置处理(颜色重构)

         }
         half GeMask(WaveStruct wave)
        {
         
	      
	        half mask = wave.position.y / _MaxWaveHeight * 0.5 + 0.5; // encode the normalized wave height into additional data
	        return mask;
        }

            WaveStruct GerstnerWave(half2 pos, float waveCountMulti, half amplitude, half direction, half wavelength, half omni, half2 omniPos)
            {
	            WaveStruct waveOut;
	            float time = _Time.y*_WindSpeed;
	            wave value calculations//
	            half3 wave = 0; // wave vector
	            half w = 6.28318 / wavelength; 
	            half wSpeed = sqrt(9.8 * w); 
	            half peak = 1.5; 
	            half qi = peak / (amplitude * w * _WaveCount);

	            direction = radians(direction);
	            half2 dirWaveInput = half2(sin(direction), cos(direction)) * (1 - omni);
	            half2 omniWaveInput = (pos - omniPos) * omni;

	            half2 windDir = normalize(dirWaveInput + omniWaveInput); 
	            half dir = dot(windDir, pos - (omniPos * omni)); 
	            half calc = dir * w + -time * wSpeed; 
	            half cosCalc = cos(calc);
	            half sinCalc = sin(calc); 
	            wave.xz = qi * amplitude * windDir.xy * cosCalc;
	            wave.y = ((sinCalc * amplitude)) * waveCountMulti;
	            half wa = w * amplitude;
	            // normal vector
	            half3 n = half3(-(windDir.xy * wa * cosCalc),
					            1-(qi * wa * sinCalc));
	            waveOut.position = wave * saturate(amplitude * 10000);
	            waveOut.normal = (n.xzy * waveCountMulti);

	            return waveOut;
            }
            inline void SampleWaves(float3 position, half opacity, Wave Custom_w[6] ,inout WaveStruct waveOut)
            {
	            half2 pos = position.xz;
	            waveOut.position = 0;
	            waveOut.normal = 0;
	            half waveCountMulti = 1.0 / _WaveCount;
	            half3 opacityMask = saturate(half3(3, 3, 1) * opacity);

	            UNITY_LOOP
	            for(int i = 0; i < _WaveCount; i++)
	            {
		            WaveStruct wave = GerstnerWave(pos,
								            waveCountMulti,
								            Custom_w[i].amplitude,
								            Custom_w[i].direction,
								            Custom_w[i].wavelength,
								            0,
								            half2(0,0)); // calculate the wave

		            waveOut.position += wave.position; // add the position
		            waveOut.normal += wave.normal; // add the normal
	                }
	                    waveOut.position *= opacityMask;
	                    waveOut.normal *= half3(opacity, 1, opacity);
                }
            Varyings vert(Attributes v)
            {
                Varyings o     = (Varyings)0;
                half time     =_Time.y*_WindSpeed;
                half3 normalWS=half3(0,1,0);
                o.posWS        =TransformObjectToWorld(v.positionOS.xyz);
                o.texcoord1.x  =((noise((o.posWS.xz * 0.5) + time) + noise((o.posWS.xz * 1) + time)) * 0.25 - 0.5) + 1;
                o.texcoord.xy  =o.posWS.xz * 0.1h + time * 0.05h + (o.texcoord1.x * 0.1);
               
            
                _Wave[0]       =(Wave)0;
                _Wave[1]       =(Wave)0;
                _Wave[2]       =(Wave)0;
                _Wave[3]       =(Wave)0;
                _Wave[4]       =(Wave)0;
                _Wave[5]       =(Wave)0;
             
                for(int j = 0; j < _WaveCount; j++)
                {  
                   _Wave[j].amplitude =_AvgSwell*randomSeedList[j].x;
                   _Wave[j].direction =_WindDirection+randomSeedList[j].y;
                   _Wave[j].wavelength=_AvgWaveLength*randomSeedList[j].z;
               
                }
                WaveStruct wave;
                SampleWaves( o.posWS ,1, _Wave,wave);
               	o.normalWS = wave.normal.xyz;
                o.posWS += wave.position;
                o.texcoord1.y=   GeMask(wave);
                o.positionCS = TransformWorldToHClip( o.posWS);

                return o;
            }
 
            half4 frag(Varyings i) : SV_Target
            {       
                half3 BaseColor=_Color.xyz;
               	half2 detailBump1 = SAMPLE_TEXTURE2D(_SurfaceMap, sampler_SurfaceMap, i.texcoord.xy).xy * 2 - 1;
	           	half3 foamMap = SAMPLE_TEXTURE2D(_FoamMap, sampler_FoamMap,  i.texcoord.xy).rgb; 

	            half distance_foam= saturate(length(foamMap * i.texcoord1.yyy) * 1.5 - _AdjustFoam);
             
                i.normalWS += half3(detailBump1.x, 0, detailBump1.y) * _BumpScale;
	            i.normalWS = normalize(i.normalWS);
                half3 normalWS= i.normalWS;
              
                Light mainLight = GetMainLight();
                foamMap=mainLight.color;

                float3 viewDir=GetWorldSpaceNormalizeViewDir(i.posWS);
                half3 brdfDiffuse =BaseColor.xyz*(kDirSpec.a*(1-_Metallic));
                half3 brdfSpec=lerp(kDirSpec.xyz,BaseColor.xyz,_Metallic);
                half3 lightDir=normalize(_LightDir);
                //NOL
                half nl =saturate(dot(normalWS, lightDir));
                float3 halfDir = normalize(viewDir + lightDir);
                half nh = saturate(dot(normalWS, halfDir));
                float nv = saturate(dot(normalWS, viewDir));
                float vh = saturate(dot(viewDir, lightDir));
                float hl = saturate(dot(halfDir, lightDir));

                half3 radiance=mainLight.color*nl;
                half3 brdf =brdfDiffuse.xyz;
                half  roughness2=max(_Roughness*_Roughness,HALF_MIN);
                half  d=nh*nh*(roughness2-1)+1.0001f;
                half  d2=d*d;
                half  LdotH2=hl*hl;
                half  specTerm=roughness2/(d2*max(half(0.1),LdotH2)*(_Roughness*4+2));
                 brdf           =brdf*radiance;



                 half3 EnivormentSpecColor=half3(0,0,0);
                 half3 reflectVector=reflect(-viewDir, normalWS);
                 half  NoV=saturate(dot(normalWS, viewDir));
                 half fresnelTerm = (1.0 - NoV)*(1.0 - NoV)*(1.0 - NoV)*(1.0 - NoV);
                 half mip = _Roughness*(1.7-0.7*_Roughness)*6;
                  half4 encodedIrradiance;
                 #if !defined(_CUSTOMREFLECT_ON)
                     encodedIrradiance= half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip));
                     #if defined(UNITY_USE_NATIVE_HDR)
                         EnivormentSpecColor =encodedIrradiance.rgb;
                     #else
                        EnivormentSpecColor =DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR);
                     #endif
                #else
                      encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(_ReflectCube, sampler_ReflectCube, reflectVector, mip));
                     #if defined(UNITY_USE_NATIVE_HDR)
                         EnivormentSpecColor =encodedIrradiance.rgb;
                     #else
                        EnivormentSpecColor =DecodeHDREnvironment(encodedIrradiance, _ReflectCube_HDR);
                     #endif
                #endif

                half surfaceReduction=1/(_Roughness*_Roughness+1);
                half  grazingTerm=max(max(brdfSpec.r, brdfSpec.g), brdfSpec.b);
                half3 environment_Spec=surfaceReduction*lerp(brdfSpec,grazingTerm,fresnelTerm);
                half3 GIColor=half3(0,0,0);

                  #if !defined(_CUSTOMREFLECT_ON)
                     encodedIrradiance= half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip));
                     #if defined(UNITY_USE_NATIVE_HDR)
                         GIColor =encodedIrradiance.rgb;
                     #else
                        GIColor =DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR);
                     #endif
                #else
                      encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(_ReflectCube, sampler_ReflectCube, reflectVector, mip));
                     #if defined(UNITY_USE_NATIVE_HDR)
                         GIColor =encodedIrradiance.rgb;
                     #else
                        GIColor =DecodeHDREnvironment(encodedIrradiance, _ReflectCube_HDR);
                     #endif
                #endif

                foamMap+=GIColor;
                half3 diffuse_color=GIColor*brdfDiffuse;
                diffuse_color+=EnivormentSpecColor*environment_Spec;
                diffuse_color=diffuse_color+brdf.xyz;
                diffuse_color=lerp(diffuse_color,foamMap,distance_foam);
                #if defined(_OPENADJUST_ON)
                    diffuse_color= ACESFilm(diffuse_color,2.51,0.03,2.43,0.59,0.14)+specTerm*brdfSpec*radiance;
                #else
                    diffuse_color+=specTerm*brdfSpec*radiance;
                #endif
                return half4(diffuse_color   .xyz,1);
            
            }
            ENDHLSL
        }

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值