Search Unity

The Community Ocean Shader (Open Source) Unity 5

Discussion in 'Shaders' started by laurent-clave, Nov 30, 2015.

  1. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    I everyone !

    I created a new version of the mobile ocean (based on http://forum.unity3d.com/threads/wanted-ocean-shader.16540) for unity 5 and mobile.

    The repo

    Video of project :


    I have two problems:
    - The fog no working
    - I added a foam normal map slot but I do not know how to set up in shader code



    If you can help me it's great ;)
     
  2. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Link to shader code

    Code (CSharp):
    1. Shader "Mobile/Ocean" {
    2.     Properties {
    3.         _SurfaceColor ("SurfaceColor", Color) = (1,1,1,1)
    4.         _WaterColor ("WaterColor", Color) = (1,1,1,1)
    5.         _Refraction ("Refraction (RGB)", 2D) = "white" {}
    6.         _Reflection ("Reflection (RGB)", 2D) = "white" {}
    7.         _Bump ("Bump (RGB)", 2D) = "bump" {}
    8.         _Foam("Foam (RGB)", 2D) = "white" {}
    9.         _FoamBump ("Foam B(RGB)", 2D) = "bump" {}
    10.         _FoamFactor("Foam Factor", Range(0,3)) = 1.8
    11.         _Size ("Size", Vector) = (1, 1, 1, 1)
    12.         _SunDir ("SunDir", Vector) = (0.3, -0.6, -1, 0)
    13.         _WaveOffset ("Wave speed", Vector) = (19,9,-16,-7)
    14.        
    15.         _SurfaceColorLod1 ("Surface Color LOD1", Color) = (1,1,1,0.5)
    16.         _WaterColorLod1 ("Water Color LOD1", Color) = (1,1,1,0.5)
    17.         _WaterTex ("Water LOD1 (RGB)", 2D) = "white" {}
    18.         _WaterLod1Alpha ("Water Transparency", Range(0,1)) = 0.95
    19.     }
    20.     SubShader {
    21.         Tags { "RenderType" = "Opaque" "Queue"="Geometry"}
    22.         LOD 2
    23.         Pass {
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.             #pragma multi_compile_fog
    28.             #include "UnityCG.cginc"
    29.  
    30.             struct v2f {
    31.                 half4 pos : SV_POSITION;
    32.                 half4  projTexCoord : TEXCOORD0;
    33.                 half4  bumpTexCoord : TEXCOORD1;
    34.                 float3  viewDir : TEXCOORD2;
    35.                 float3  objSpaceNormal : TEXCOORD3;
    36.                 float3  lightDir : TEXCOORD4;
    37.                 UNITY_FOG_COORDS(7)
    38.                 float2  foamStrengthAndDistance : TEXCOORD5;
    39.             };
    40.  
    41.             half4 _Size;
    42.             half4 _SunDir;
    43.             uniform half4 _WaveOffset;
    44.  
    45.             v2f vert (appdata_tan v) {
    46.                 v2f o;
    47.    
    48.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    49.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    50.                 o.foamStrengthAndDistance.x = v.tangent.w;
    51.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    52.    
    53.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    54.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    55.                 o.projTexCoord = tmpProj;
    56.  
    57.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    58.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    59.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    60.    
    61.                 o.objSpaceNormal = v.normal;
    62.                 o.viewDir = mul(rotation, objSpaceViewDir);
    63.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    64.                
    65.                 UNITY_TRANSFER_FOG(o, o.pos);
    66.  
    67.                 return o;
    68.             }
    69.  
    70.             sampler2D _Refraction;
    71.             sampler2D _Reflection;
    72.             sampler2D _Bump;
    73.             sampler2D _Foam;
    74.             sampler2D _FoamBump;
    75.             half _FoamFactor;
    76.             half4 _SurfaceColor;
    77.             half4 _WaterColor;
    78.  
    79.             half4 frag (v2f i) : COLOR {
    80.                 half3 normViewDir = normalize(i.viewDir);
    81.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    82.                
    83.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    84.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    85.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    86.                 float2 projTexCoord = 0.5 * i.projTexCoord.xy * float2(1, _ProjectionParams.x) / i.projTexCoord.w + float2(0.5, 0.5);
    87.                 half4 result = half4(0, 0, 0, 1);
    88.                 float2 bumpSampleOffset = i.objSpaceNormal.xz * 0.05 + tangentNormal.xy * 0.05;
    89.    
    90.                 half3 reflection = tex2D(_Reflection, projTexCoord.xy + bumpSampleOffset) * _SurfaceColor;
    91.                 half3 refraction = tex2D(_Refraction, projTexCoord.xy + bumpSampleOffset) * _WaterColor;
    92.  
    93.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    94.                 float bias = 0.06;
    95.                 float power = 4.0;
    96.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    97.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    98.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    99.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    100.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    101.  
    102.                 result.rgb = lerp(refraction, reflection, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    103.                 return result;
    104.             }
    105.  
    106.        
    107.  
    108.             ENDCG
    109.         }
    110.     }
    111.        
    112.     SubShader {
    113.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    114.         LOD 1
    115.         Pass {
    116.             Blend One OneMinusSrcAlpha
    117.             CGPROGRAM
    118.             #pragma vertex vert
    119.             #pragma fragment frag
    120.             #include "UnityCG.cginc"
    121.  
    122.             struct v2f {
    123.                 float4 pos : SV_POSITION;
    124.                 float2  bumpTexCoord : TEXCOORD1;
    125.                 float3  viewDir : TEXCOORD2;
    126.                 float3  objSpaceNormal : TEXCOORD3;
    127.                 float3  lightDir : TEXCOORD4;
    128.                 float2  foamStrengthAndDistance : TEXCOORD5;
    129.             };
    130.  
    131.             half4 _Size;
    132.             half4 _SunDir;
    133.             sampler2D _WaterTex;
    134.             uniform half4 _WaveOffset;
    135.            
    136.             v2f vert (appdata_tan v) {
    137.                 v2f o;
    138.    
    139.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    140.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    141.                 o.foamStrengthAndDistance.x = v.tangent.w;
    142.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    143.    
    144.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    145.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    146.  
    147.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    148.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    149.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    150.    
    151.                 o.objSpaceNormal = v.normal;
    152.                 o.viewDir = mul(rotation, objSpaceViewDir);
    153.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    154.  
    155.                 return o;
    156.             }
    157.  
    158.             sampler2D _Bump;
    159.             sampler2D _Foam;
    160.             half4 _SurfaceColorLod1;
    161.             half _FoamFactor;
    162.             half4 _WaterColorLod1;
    163.             half _WaterLod1Alpha;
    164.            
    165.             half4 frag (v2f i) : COLOR {
    166.                 half3 normViewDir = normalize(i.viewDir);
    167.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    168.                 half2 buv2 = half2(i.bumpTexCoord.x - _WaveOffset.z * 0.05, i.bumpTexCoord.y - _WaveOffset.w * 0.05);
    169.                
    170.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    171.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    172.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    173.  
    174.                 half4 result = half4(0, 0, 0, 1);
    175.                 half3 tex = tex2D(_WaterTex, buv2*2) * _WaterColorLod1;
    176.                
    177.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    178.                 float bias = 0.06;
    179.                 float power = 4.0;
    180.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    181.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    182.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    183.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    184.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    185.                
    186.                 result.a = _WaterLod1Alpha;
    187.                 result.rgb = lerp(tex, _SurfaceColorLod1, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    188.                
    189.                 return result;
    190.             }
    191.             ENDCG
    192.            
    193.  
    194.         }
    195.     }
    196.     FallBack "Diffuse", 1
    197. }
    198.  
     
    Farelle likes this.
  3. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    I think you can fix your fog by adding this line before your return: UNITY_APPLY_FOG(i.fogCoord, result);
     
    twobob likes this.
  4. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Hi Phantomx !

    Thank you, the fog working ;)
     
  5. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    I confirm that this works.

    I had made some optimizations in the old community project. I will try to import them in your project and get back to you.

    Also I will fiddle around with the idea of baking an fft cycle and use this instead of realtime calculations of the fft.
    Perhaps for a better result 2 baked fft cycles could be blended.
     
  6. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    ok thank you elias !
     
  7. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Here is the shader with normals on the foam:

    Code (CSharp):
    1. Shader "Mobile/Ocean" {
    2.     Properties {
    3.         _SurfaceColor ("SurfaceColor", Color) = (1,1,1,1)
    4.         _WaterColor ("WaterColor", Color) = (1,1,1,1)
    5.         _Refraction ("Refraction (RGB)", 2D) = "white" {}
    6.         _Reflection ("Reflection (RGB)", 2D) = "white" {}
    7.         _Bump ("Bump (RGB)", 2D) = "bump" {}
    8.         _Foam("Foam (RGB)", 2D) = "white" {}
    9.         _FoamBump ("Foam B(RGB)", 2D) = "bump" {}
    10.         _FoamFactor("Foam Factor", Range(0,3)) = 1.8
    11.         _Size ("Size", Vector) = (1, 1, 1, 1)
    12.         _SunDir ("SunDir", Vector) = (0.3, -0.6, -1, 0)
    13.         _WaveOffset ("Wave speed", Vector) = (19,9,-16,-7)
    14.      
    15.         _SurfaceColorLod1 ("Surface Color LOD1", Color) = (1,1,1,0.5)
    16.         _WaterColorLod1 ("Water Color LOD1", Color) = (1,1,1,0.5)
    17.         _WaterTex ("Water LOD1 (RGB)", 2D) = "white" {}
    18.         _WaterLod1Alpha ("Water Transparency", Range(0,1)) = 0.95
    19.     }
    20.     SubShader {
    21.         Tags { "RenderType" = "Opaque" "Queue"="Geometry"}
    22.         LOD 2
    23.         Pass {
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.             #pragma multi_compile_fog
    28.             #include "UnityCG.cginc"
    29.  
    30.             struct v2f {
    31.                 half4 pos : SV_POSITION;
    32.                 half4  projTexCoord : TEXCOORD0;
    33.                 half4  bumpTexCoord : TEXCOORD1;
    34.                 float3  viewDir : TEXCOORD2;
    35.                 float3  objSpaceNormal : TEXCOORD3;
    36.                 float3  lightDir : TEXCOORD4;
    37.                 UNITY_FOG_COORDS(7)
    38.                 float2  foamStrengthAndDistance : TEXCOORD5;
    39.             };
    40.  
    41.             half4 _Size;
    42.             half4 _SunDir;
    43.             uniform half4 _WaveOffset;
    44.  
    45.             v2f vert (appdata_tan v) {
    46.                 v2f o;
    47.  
    48.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    49.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    50.                 o.foamStrengthAndDistance.x = v.tangent.w;
    51.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    52.  
    53.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    54.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    55.                 o.projTexCoord = tmpProj;
    56.  
    57.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    58.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    59.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    60.  
    61.                 o.objSpaceNormal = v.normal;
    62.                 o.viewDir = mul(rotation, objSpaceViewDir);
    63.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    64.              
    65.                 UNITY_TRANSFER_FOG(o, o.pos);
    66.  
    67.                 return o;
    68.             }
    69.  
    70.             sampler2D _Refraction;
    71.             sampler2D _Reflection;
    72.             sampler2D _Bump;
    73.             sampler2D _Foam;
    74.             sampler2D _FoamBump;
    75.             half _FoamFactor;
    76.             half4 _SurfaceColor;
    77.             half4 _WaterColor;
    78.  
    79.             half4 frag (v2f i) : COLOR {
    80.                 half3 normViewDir = normalize(i.viewDir);
    81.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    82.              
    83.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    84.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    85.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    86.  
    87.                 half3 tangentNormalA0 = (tex2D(_FoamBump, i.bumpTexCoord.xy) * 2.0) - 1;
    88.                 half3 tangentNormalA1 = (tex2D(_FoamBump, i.bumpTexCoord.xy) * 2.0) - 1;
    89.                 half3 tangentNormalA = normalize(tangentNormalA0 + tangentNormalA1);
    90.  
    91.                 half3 normalsCombined = (tangentNormal+tangentNormalA)*0.5;
    92.  
    93.                 float2 projTexCoord = 0.5 * i.projTexCoord.xy * float2(1, _ProjectionParams.x) / i.projTexCoord.w + float2(0.5, 0.5);
    94.                 half4 result = half4(0, 0, 0, 1);
    95.                 float2 bumpSampleOffset = i.objSpaceNormal.xz * 0.05 + tangentNormal.xy * 0.05 +  tangentNormalA.xy * 0.05;
    96.  
    97.                 half3 reflection = tex2D( _Reflection, projTexCoord.xy + bumpSampleOffset ) * _SurfaceColor;
    98.                 half3 refraction = tex2D( _Refraction, projTexCoord.xy + bumpSampleOffset ) * _WaterColor;
    99.  
    100.  
    101.                 float fresnelLookup = dot(normalsCombined, normViewDir);
    102.  
    103.                 float bias = 0.06;
    104.                 float power = 4.0;
    105.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    106.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor ;
    107.  
    108.                 half foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength   ;
    109.  
    110.  
    111.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    112.                 float specular = pow(max(dot(halfVec,  normalsCombined) , 0.0), 250.0);
    113.  
    114.                 result.rgb = lerp(refraction, reflection, fresnelTerm) + clamp(foam , 0.0, 1.0) + specular;
    115.  
    116.                 UNITY_APPLY_FOG(i.fogCoord, result);
    117.  
    118.                 return result;
    119.             }
    120.  
    121.      
    122.  
    123.             ENDCG
    124.         }
    125.     }
    126.      
    127.     SubShader {
    128.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    129.         LOD 1
    130.         Pass {
    131.             Blend One OneMinusSrcAlpha
    132.             CGPROGRAM
    133.             #pragma vertex vert
    134.             #pragma fragment frag
    135.             #include "UnityCG.cginc"
    136.  
    137.             struct v2f {
    138.                 float4 pos : SV_POSITION;
    139.                 float2  bumpTexCoord : TEXCOORD1;
    140.                 float3  viewDir : TEXCOORD2;
    141.                 float3  objSpaceNormal : TEXCOORD3;
    142.                 float3  lightDir : TEXCOORD4;
    143.                 float2  foamStrengthAndDistance : TEXCOORD5;
    144.             };
    145.  
    146.             half4 _Size;
    147.             half4 _SunDir;
    148.             sampler2D _WaterTex;
    149.             uniform half4 _WaveOffset;
    150.          
    151.             v2f vert (appdata_tan v) {
    152.                 v2f o;
    153.  
    154.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    155.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    156.                 o.foamStrengthAndDistance.x = v.tangent.w;
    157.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    158.  
    159.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    160.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    161.  
    162.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    163.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    164.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    165.  
    166.                 o.objSpaceNormal = v.normal;
    167.                 o.viewDir = mul(rotation, objSpaceViewDir);
    168.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    169.  
    170.                 return o;
    171.             }
    172.  
    173.             sampler2D _Bump;
    174.             sampler2D _Foam;
    175.             half4 _SurfaceColorLod1;
    176.             half _FoamFactor;
    177.             half4 _WaterColorLod1;
    178.             half _WaterLod1Alpha;
    179.          
    180.             half4 frag (v2f i) : COLOR {
    181.                 half3 normViewDir = normalize(i.viewDir);
    182.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    183.                 half2 buv2 = half2(i.bumpTexCoord.x - _WaveOffset.z * 0.05, i.bumpTexCoord.y - _WaveOffset.w * 0.05);
    184.              
    185.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    186.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    187.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    188.  
    189.                 half4 result = half4(0, 0, 0, 1);
    190.                 half3 tex = tex2D(_WaterTex, buv2*2) * _WaterColorLod1;
    191.              
    192.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    193.                 float bias = 0.06;
    194.                 float power = 4.0;
    195.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    196.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    197.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    198.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    199.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    200.              
    201.                 result.a = _WaterLod1Alpha;
    202.                 result.rgb = lerp(tex, _SurfaceColorLod1, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    203.              
    204.                 return result;
    205.             }
    206.             ENDCG
    207.          
    208.  
    209.         }
    210.     }
    211.     FallBack "Diffuse", 1
    212. }
    213.  
     
    Last edited: Nov 30, 2015
  8. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    And here with extra specular control:

    Code (CSharp):
    1. Shader "Mobile/Ocean" {
    2.     Properties {
    3.         _SurfaceColor ("SurfaceColor", Color) = (1,1,1,1)
    4.         _WaterColor ("WaterColor", Color) = (1,1,1,1)
    5.  
    6.         _Specularity ("Specularity", Range(0.01,0.5)) = 0.1
    7.  
    8.         _Refraction ("Refraction (RGB)", 2D) = "white" {}
    9.         _Reflection ("Reflection (RGB)", 2D) = "white" {}
    10.         _Bump ("Bump (RGB)", 2D) = "bump" {}
    11.         _Foam("Foam (RGB)", 2D) = "white" {}
    12.         _FoamBump ("Foam B(RGB)", 2D) = "bump" {}
    13.         _FoamFactor("Foam Factor", Range(0,3)) = 1.8
    14.         _Size ("Size", Vector) = (1, 1, 1, 1)
    15.         _SunDir ("SunDir", Vector) = (0.3, -0.6, -1, 0)
    16.         _WaveOffset ("Wave speed", Vector) = (19,9,-16,-7)
    17.      
    18.         _SurfaceColorLod1 ("Surface Color LOD1", Color) = (1,1,1,0.5)
    19.         _WaterColorLod1 ("Water Color LOD1", Color) = (1,1,1,0.5)
    20.         _WaterTex ("Water LOD1 (RGB)", 2D) = "white" {}
    21.         _WaterLod1Alpha ("Water Transparency", Range(0,1)) = 0.95
    22.     }
    23.     SubShader {
    24.         Tags { "RenderType" = "Opaque" "Queue"="Geometry"}
    25.         LOD 2
    26.         Pass {
    27.             CGPROGRAM
    28.             #pragma vertex vert
    29.             #pragma fragment frag
    30.             #pragma multi_compile_fog
    31.             #include "UnityCG.cginc"
    32.  
    33.             struct v2f {
    34.                 half4 pos : SV_POSITION;
    35.                 half4  projTexCoord : TEXCOORD0;
    36.                 half4  bumpTexCoord : TEXCOORD1;
    37.                 float3  viewDir : TEXCOORD2;
    38.                 float3  objSpaceNormal : TEXCOORD3;
    39.                 float3  lightDir : TEXCOORD4;
    40.                 UNITY_FOG_COORDS(7)
    41.                 float2  foamStrengthAndDistance : TEXCOORD5;
    42.             };
    43.  
    44.             half4 _Size;
    45.             half4 _SunDir;
    46.             uniform half4 _WaveOffset;
    47.  
    48.             v2f vert (appdata_tan v) {
    49.                 v2f o;
    50.  
    51.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    52.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    53.                 o.foamStrengthAndDistance.x = v.tangent.w;
    54.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    55.  
    56.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    57.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    58.                 o.projTexCoord = tmpProj;
    59.  
    60.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    61.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    62.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    63.  
    64.                 o.objSpaceNormal = v.normal;
    65.                 o.viewDir = mul(rotation, objSpaceViewDir);
    66.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    67.              
    68.                 UNITY_TRANSFER_FOG(o, o.pos);
    69.  
    70.                 return o;
    71.             }
    72.  
    73.             sampler2D _Refraction;
    74.             sampler2D _Reflection;
    75.             sampler2D _Bump;
    76.             sampler2D _Foam;
    77.             sampler2D _FoamBump;
    78.             half _FoamFactor;
    79.             half4 _SurfaceColor;
    80.             half4 _WaterColor;
    81.             half _Specularity;
    82.  
    83.             half4 frag (v2f i) : COLOR {
    84.                 half3 normViewDir = normalize(i.viewDir);
    85.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    86.              
    87.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    88.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    89.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    90.  
    91.                 half3 tangentNormalA0 = (tex2D(_FoamBump, i.bumpTexCoord.xy) * 2.0) - 1;
    92.                 half3 tangentNormalA1 = (tex2D(_FoamBump, i.bumpTexCoord.xy) * 2.0) - 1;
    93.                 half3 tangentNormalA = normalize(tangentNormalA0 + tangentNormalA1);
    94.  
    95.                 half3 normalsCombined = (tangentNormal +tangentNormalA)*0.5;
    96.  
    97.                 float2 projTexCoord = 0.5 * i.projTexCoord.xy * float2(1, _ProjectionParams.x) / i.projTexCoord.w + float2(0.5, 0.5);
    98.                 half4 result = half4(0, 0, 0, 1);
    99.                 float2 bumpSampleOffset = i.objSpaceNormal.xz * 0.05 + tangentNormal.xy * 0.05 +  tangentNormalA.xy * 0.05;
    100.  
    101.                 half3 reflection = tex2D( _Reflection, projTexCoord.xy + bumpSampleOffset ) * _SurfaceColor;
    102.                 half3 refraction = tex2D( _Refraction, projTexCoord.xy + bumpSampleOffset ) * _WaterColor;
    103.  
    104.  
    105.                 float fresnelLookup = dot(normalsCombined, normViewDir);
    106.  
    107.                 float bias = 0.06;
    108.                 float power = 4.0;
    109.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    110.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor ;
    111.  
    112.                 half foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength   ;
    113.  
    114.  
    115.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    116.                 float specular = pow(max(dot(halfVec,  normalsCombined) , 0.0), 250.0 * _Specularity );
    117.  
    118.                 result.rgb = lerp(refraction, reflection, fresnelTerm) + clamp(foam, 0.0, 1.0) + specular;
    119.  
    120.                 UNITY_APPLY_FOG(i.fogCoord, result);
    121.  
    122.                 return result;
    123.             }
    124.  
    125.      
    126.  
    127.             ENDCG
    128.         }
    129.     }
    130.      
    131.     SubShader {
    132.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    133.         LOD 1
    134.         Pass {
    135.             Blend One OneMinusSrcAlpha
    136.             CGPROGRAM
    137.             #pragma vertex vert
    138.             #pragma fragment frag
    139.             #include "UnityCG.cginc"
    140.  
    141.             struct v2f {
    142.                 float4 pos : SV_POSITION;
    143.                 float2  bumpTexCoord : TEXCOORD1;
    144.                 float3  viewDir : TEXCOORD2;
    145.                 float3  objSpaceNormal : TEXCOORD3;
    146.                 float3  lightDir : TEXCOORD4;
    147.                 float2  foamStrengthAndDistance : TEXCOORD5;
    148.             };
    149.  
    150.             half4 _Size;
    151.             half4 _SunDir;
    152.             sampler2D _WaterTex;
    153.             uniform half4 _WaveOffset;
    154.          
    155.             v2f vert (appdata_tan v) {
    156.                 v2f o;
    157.  
    158.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    159.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    160.                 o.foamStrengthAndDistance.x = v.tangent.w;
    161.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    162.  
    163.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    164.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    165.  
    166.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    167.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    168.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    169.  
    170.                 o.objSpaceNormal = v.normal;
    171.                 o.viewDir = mul(rotation, objSpaceViewDir);
    172.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    173.  
    174.                 return o;
    175.             }
    176.  
    177.             sampler2D _Bump;
    178.             sampler2D _Foam;
    179.             half4 _SurfaceColorLod1;
    180.             half _FoamFactor;
    181.             half4 _WaterColorLod1;
    182.             half _WaterLod1Alpha;
    183.          
    184.             half4 frag (v2f i) : COLOR {
    185.                 half3 normViewDir = normalize(i.viewDir);
    186.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    187.                 half2 buv2 = half2(i.bumpTexCoord.x - _WaveOffset.z * 0.05, i.bumpTexCoord.y - _WaveOffset.w * 0.05);
    188.              
    189.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    190.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    191.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    192.  
    193.                 half4 result = half4(0, 0, 0, 1);
    194.                 half3 tex = tex2D(_WaterTex, buv2*2) * _WaterColorLod1;
    195.              
    196.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    197.                 float bias = 0.06;
    198.                 float power = 4.0;
    199.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    200.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    201.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    202.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    203.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    204.              
    205.                 result.a = _WaterLod1Alpha;
    206.                 result.rgb = lerp(tex, _SurfaceColorLod1, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    207.              
    208.                 return result;
    209.             }
    210.             ENDCG
    211.          
    212.  
    213.         }
    214.     }
    215.     FallBack "Diffuse", 1
    216. }
    217.  
     
    Last edited: Nov 30, 2015
    twobob and Manny Calavera like this.
  9. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Nice Elias !!!!


    The render is great ;)
     
    twobob and elias_t like this.
  10. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Looks good!

    I am making now another version of the shader with a more correct approach on the foam bump.

    Does this work on your Android? Because on an Xperia S I have artifacts.
     
  11. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    no artefacts on my Idol 3 4.7. The render is very nice.
    Screenshot directly from my mobile :



     
    elias_t likes this.
  12. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Ok then.

    I have updated the previous versions of the shader. I forgot to add one scroll uv for the scrolling wave normals.
    The foam is less specular now.

    Also here is a more compact (and I believe faster) shader which allows a day night cycle.
    I added also a sunlight color which you should update through script.
    This will allow the foam to get darker at night.


    Code (CSharp):
    1. Shader "Mobile/OceanB" {
    2.     Properties {
    3.         _SurfaceColor ("SurfaceColor", Color) = (1,1,1,1)
    4.         _WaterColor ("WaterColor", Color) = (1,1,1,1)
    5.  
    6.         _Specularity ("Specularity", Range(0.01,1)) = 0.3
    7.  
    8.         _SunColor ("SunColor", Color) = (1,1,0.901,1)
    9.  
    10.         _Refraction ("Refraction (RGB)", 2D) = "white" {}
    11.         _Reflection ("Reflection (RGB)", 2D) = "white" {}
    12.         _Bump ("Bump (RGB)", 2D) = "bump" {}
    13.         _Foam("Foam (RGB)", 2D) = "white" {}
    14.         _FoamBump ("Foam B(RGB)", 2D) = "bump" {}
    15.         _FoamFactor("Foam Factor", Range(0,3)) = 1.8
    16.         _Size ("Size", Vector) = (1, 1, 1, 1)
    17.         _SunDir ("SunDir", Vector) = (0.3, -0.6, -1, 0)
    18.         _WaveOffset ("Wave speed", Vector) = (19,9,-16,-7)
    19.      
    20.         _SurfaceColorLod1 ("Surface Color LOD1", Color) = (1,1,1,0.5)
    21.         _WaterColorLod1 ("Water Color LOD1", Color) = (1,1,1,0.5)
    22.         _WaterTex ("Water LOD1 (RGB)", 2D) = "white" {}
    23.         _WaterLod1Alpha ("Water Transparency", Range(0,1)) = 0.95
    24.     }
    25.     SubShader {
    26.         Tags { "RenderType" = "Opaque" "Queue"="Geometry"}
    27.         LOD 2
    28.         Pass {
    29.             CGPROGRAM
    30.             #pragma vertex vert
    31.             #pragma fragment frag
    32.             #pragma multi_compile_fog
    33.             #include "UnityCG.cginc"
    34.  
    35.             struct v2f {
    36.                 half4 pos : SV_POSITION;
    37.                 half4  projTexCoord : TEXCOORD0;
    38.                 half4  bumpTexCoord : TEXCOORD1;
    39.                 float3  viewDir : TEXCOORD2;
    40.                 float3  objSpaceNormal : TEXCOORD3;
    41.                 float3  lightDir : TEXCOORD4;
    42.                 UNITY_FOG_COORDS(7)
    43.                 float2  foamStrengthAndDistance : TEXCOORD5;
    44.             };
    45.  
    46.             half4 _Size;
    47.             half4 _SunDir;
    48.             uniform half4 _WaveOffset;
    49.  
    50.             v2f vert (appdata_tan v) {
    51.                 v2f o;
    52.  
    53.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    54.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    55.                 o.foamStrengthAndDistance.x = v.tangent.w;
    56.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    57.  
    58.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    59.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    60.                 o.projTexCoord = tmpProj;
    61.  
    62.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    63.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    64.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    65.  
    66.                 o.objSpaceNormal = v.normal;
    67.                 o.viewDir = mul(rotation, objSpaceViewDir);
    68.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    69.              
    70.                 UNITY_TRANSFER_FOG(o, o.pos);
    71.  
    72.                 return o;
    73.             }
    74.  
    75.             sampler2D _Refraction;
    76.             sampler2D _Reflection;
    77.             sampler2D _Bump;
    78.             sampler2D _Foam;
    79.             sampler2D _FoamBump;
    80.             half _FoamFactor;
    81.             half4 _SurfaceColor;
    82.             half4 _WaterColor;
    83.             half _Specularity;
    84.             half4 _SunColor;
    85.  
    86.             half4 frag (v2f i) : COLOR {
    87.                 half3 normViewDir = normalize(i.viewDir);
    88.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    89.              
    90.                 half3 tangentNormal0 = ( tex2D(_Bump, buv.xy) + tex2D(_FoamBump, i.bumpTexCoord.xy) ) - 1;
    91.                 half3 tangentNormal1 = ( tex2D(_Bump, buv.zw) + tex2D(_FoamBump, i.bumpTexCoord.xy) ) - 1;
    92.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    93.              
    94.  
    95.                 float2 projTexCoord = 0.5 * i.projTexCoord.xy * float2(1, _ProjectionParams.x) / i.projTexCoord.w + float2(0.5, 0.5);
    96.                 half4 result = half4(0, 0, 0, 1);
    97.                 float2 bumpSampleOffset = i.objSpaceNormal.xz * 0.05 + tangentNormal.xy * 0.05;
    98.  
    99.                 half3 reflection = tex2D( _Reflection, projTexCoord.xy + bumpSampleOffset ) * _SurfaceColor ;
    100.                 half3 refraction = tex2D( _Refraction, projTexCoord.xy + bumpSampleOffset ) * _WaterColor ;
    101.  
    102.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    103.                 half foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;// * UNITY_LIGHTMODEL_AMBIENT.b;
    104.  
    105.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    106.  
    107.                 float bias = 0.06;
    108.                 float power = 4.0;
    109.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    110.  
    111.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    112.                 float specular = pow(max(dot(halfVec,  tangentNormal) , 0.0), 250.0 * _Specularity )*(1-foam) ;
    113.  
    114.  
    115.                 //result.rgb = lerp(refraction, reflection, fresnelTerm)+ clamp(foam, 0.0, 1.0) + specular;
    116.                 result.rgb = lerp(refraction, reflection, fresnelTerm)*_SunColor.rgb + clamp(foam, 0.0, 1.0)*_SunColor.b + specular*_SunColor.rgb;
    117.  
    118.                 UNITY_APPLY_FOG(i.fogCoord, result);
    119.  
    120.                 return result;
    121.             }
    122.  
    123.      
    124.  
    125.             ENDCG
    126.         }
    127.     }
    128.      
    129.     SubShader {
    130.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    131.         LOD 1
    132.         Pass {
    133.             Blend One OneMinusSrcAlpha
    134.             CGPROGRAM
    135.             #pragma vertex vert
    136.             #pragma fragment frag
    137.             #include "UnityCG.cginc"
    138.  
    139.             struct v2f {
    140.                 float4 pos : SV_POSITION;
    141.                 float2  bumpTexCoord : TEXCOORD1;
    142.                 float3  viewDir : TEXCOORD2;
    143.                 float3  objSpaceNormal : TEXCOORD3;
    144.                 float3  lightDir : TEXCOORD4;
    145.                 float2  foamStrengthAndDistance : TEXCOORD5;
    146.             };
    147.  
    148.             half4 _Size;
    149.             half4 _SunDir;
    150.             sampler2D _WaterTex;
    151.             uniform half4 _WaveOffset;
    152.          
    153.             v2f vert (appdata_tan v) {
    154.                 v2f o;
    155.  
    156.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    157.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    158.                 o.foamStrengthAndDistance.x = v.tangent.w;
    159.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    160.  
    161.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    162.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    163.  
    164.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    165.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    166.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    167.  
    168.                 o.objSpaceNormal = v.normal;
    169.                 o.viewDir = mul(rotation, objSpaceViewDir);
    170.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    171.  
    172.                 return o;
    173.             }
    174.  
    175.             sampler2D _Bump;
    176.             sampler2D _Foam;
    177.             half4 _SurfaceColorLod1;
    178.             half _FoamFactor;
    179.             half4 _WaterColorLod1;
    180.             half _WaterLod1Alpha;
    181.          
    182.             half4 frag (v2f i) : COLOR {
    183.                 half3 normViewDir = normalize(i.viewDir);
    184.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    185.                 half2 buv2 = half2(i.bumpTexCoord.x - _WaveOffset.z * 0.05, i.bumpTexCoord.y - _WaveOffset.w * 0.05);
    186.              
    187.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    188.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    189.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    190.  
    191.                 half4 result = half4(0, 0, 0, 1);
    192.                 half3 tex = tex2D(_WaterTex, buv2*2) * _WaterColorLod1;
    193.              
    194.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    195.                 float bias = 0.06;
    196.                 float power = 4.0;
    197.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    198.  
    199.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    200.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    201.  
    202.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    203.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    204.              
    205.                 result.a = _WaterLod1Alpha;
    206.                 result.rgb = lerp(tex, _SurfaceColorLod1, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    207.              
    208.                 return result;
    209.             }
    210.             ENDCG
    211.          
    212.  
    213.         }
    214.     }
    215.     FallBack "Diffuse", 1
    216. }
    217.  
    oceanB.jpg
     
    twobob and mgear like this.
  13. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    For some reason the mask shader is not working for me now ...

    Edit: for some weird reason, if I have 2 shaders Ocean and OceanB the mask shader does not work.

    I have to delete one, reimport the project and then it works again.

    @laurent.clave, tomorrow I will try to add the optimizations in the Ocean.cs script to make it run faster.
     
    Last edited: Nov 30, 2015
  14. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Hi Elias !
    Nice thank you !

    Working for me :
     
  15. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Hi laurent.

    I made a mistake in the shader and the bump of the foam applies on all the sea.

    Here is the corrected final one.

    Code (CSharp):
    1. Shader "Mobile/Ocean" {
    2.     Properties {
    3.         _SurfaceColor ("SurfaceColor", Color) = (1,1,1,1)
    4.         _WaterColor ("WaterColor", Color) = (1,1,1,1)
    5.  
    6.         _Specularity ("Specularity", Range(0.01,1)) = 0.3
    7.  
    8.         _SunColor ("SunColor", Color) = (1,1,0.901,1)
    9.  
    10.         _Refraction ("Refraction (RGB)", 2D) = "white" {}
    11.         _Reflection ("Reflection (RGB)", 2D) = "white" {}
    12.         _Bump ("Bump (RGB)", 2D) = "bump" {}
    13.         _Foam("Foam (RGB)", 2D) = "white" {}
    14.         _FoamBump ("Foam B(RGB)", 2D) = "bump" {}
    15.         _FoamFactor("Foam Factor", Range(0,3)) = 1.8
    16.         _Size ("Size", Vector) = (1, 1, 1, 1)
    17.         _SunDir ("SunDir", Vector) = (0.3, -0.6, -1, 0)
    18.         _WaveOffset ("Wave speed", Vector) = (19,9,-16,-7)
    19.        
    20.         _SurfaceColorLod1 ("Surface Color LOD1", Color) = (1,1,1,0.5)
    21.         _WaterColorLod1 ("Water Color LOD1", Color) = (1,1,1,0.5)
    22.         _WaterTex ("Water LOD1 (RGB)", 2D) = "white" {}
    23.         _WaterLod1Alpha ("Water Transparency", Range(0,1)) = 0.95
    24.     }
    25.     SubShader {
    26.         Tags { "RenderType" = "Opaque" "Queue"="Geometry"}
    27.         LOD 2
    28.         Pass {
    29.             CGPROGRAM
    30.             #pragma vertex vert
    31.             #pragma fragment frag
    32.             #pragma multi_compile_fog
    33.             #include "UnityCG.cginc"
    34.  
    35.             struct v2f {
    36.                 half4 pos : SV_POSITION;
    37.                 half4  projTexCoord : TEXCOORD0;
    38.                 half4  bumpTexCoord : TEXCOORD1;
    39.                 float3  viewDir : TEXCOORD2;
    40.                 float3  objSpaceNormal : TEXCOORD3;
    41.                 float3  lightDir : TEXCOORD4;
    42.                 UNITY_FOG_COORDS(7)
    43.                 float2  foamStrengthAndDistance : TEXCOORD5;
    44.             };
    45.  
    46.             half4 _Size;
    47.             half4 _SunDir;
    48.             uniform half4 _WaveOffset;
    49.  
    50.             v2f vert (appdata_tan v) {
    51.                 v2f o;
    52.  
    53.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    54.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    55.                 o.foamStrengthAndDistance.x = v.tangent.w;
    56.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    57.    
    58.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    59.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    60.                 o.projTexCoord = tmpProj;
    61.  
    62.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    63.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    64.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    65.    
    66.                 o.objSpaceNormal = v.normal;
    67.                 o.viewDir = mul(rotation, objSpaceViewDir);
    68.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    69.                
    70.                 UNITY_TRANSFER_FOG(o, o.pos);
    71.  
    72.                 return o;
    73.             }
    74.  
    75.             sampler2D _Refraction;
    76.             sampler2D _Reflection;
    77.             sampler2D _Bump;
    78.             sampler2D _Foam;
    79.             sampler2D _FoamBump;
    80.             half _FoamFactor;
    81.             half4 _SurfaceColor;
    82.             half4 _WaterColor;
    83.             half _Specularity;
    84.             half4 _SunColor;
    85.  
    86.             half4 frag (v2f i) : COLOR {
    87.                 half3 normViewDir = normalize(i.viewDir);
    88.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    89.  
    90.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    91.                 half foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    92.                                
    93.                 half3 tangentNormal0 = ( tex2D(_Bump, buv.xy) * 2 ) - 1;
    94.                 half3 tangentNormal1 = ( tex2D(_Bump, buv.zw) * 2 ) - 1;
    95.  
    96.                 half3 tangentNormalA0 = (  tex2D(_FoamBump, i.bumpTexCoord.xy) * 2  - 1)*foam;
    97.  
    98.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1 + tangentNormalA0);
    99.  
    100.  
    101.                 float2 projTexCoord = 0.5 * i.projTexCoord.xy * float2(1, _ProjectionParams.x) / i.projTexCoord.w + float2(0.5, 0.5);
    102.                 half4 result = half4(0, 0, 0, 1);
    103.  
    104.                 float2 bumpSampleOffset = i.objSpaceNormal.xz * 0.05 + tangentNormal.xy * 0.05 - tangentNormalA0 ;
    105.    
    106.                 half3 reflection = tex2D( _Reflection, projTexCoord.xy + bumpSampleOffset ) * _SurfaceColor ;
    107.                 half3 refraction = tex2D( _Refraction, projTexCoord.xy + bumpSampleOffset ) * _WaterColor ;
    108.  
    109.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    110.  
    111.                 float bias = 0.06;
    112.                 float power = 4.0;
    113.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    114.  
    115.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    116.                 float specular = pow(max(dot(halfVec,  tangentNormal) , 0.0), 250.0 * _Specularity )*(1-foam) ;
    117.  
    118.  
    119.                 //result.rgb = lerp(refraction, reflection, fresnelTerm)+ clamp(foam, 0.0, 1.0) + specular;
    120.                 result.rgb = lerp(refraction, reflection, fresnelTerm)*_SunColor.rgb + clamp(foam, 0.0, 1.0)*_SunColor.b + specular*_SunColor.rgb;
    121.  
    122.                 UNITY_APPLY_FOG(i.fogCoord, result);
    123.  
    124.                 return result;
    125.             }
    126.  
    127.        
    128.  
    129.             ENDCG
    130.         }
    131.     }
    132.        
    133.     SubShader {
    134.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    135.         LOD 1
    136.         Pass {
    137.             Blend One OneMinusSrcAlpha
    138.             CGPROGRAM
    139.             #pragma vertex vert
    140.             #pragma fragment frag
    141.             #include "UnityCG.cginc"
    142.  
    143.             struct v2f {
    144.                 float4 pos : SV_POSITION;
    145.                 float2  bumpTexCoord : TEXCOORD1;
    146.                 float3  viewDir : TEXCOORD2;
    147.                 float3  objSpaceNormal : TEXCOORD3;
    148.                 float3  lightDir : TEXCOORD4;
    149.                 float2  foamStrengthAndDistance : TEXCOORD5;
    150.             };
    151.  
    152.             half4 _Size;
    153.             half4 _SunDir;
    154.             sampler2D _WaterTex;
    155.             uniform half4 _WaveOffset;
    156.            
    157.             v2f vert (appdata_tan v) {
    158.                 v2f o;
    159.    
    160.                 o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5;
    161.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    162.                 o.foamStrengthAndDistance.x = v.tangent.w;
    163.                 o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0);
    164.    
    165.                   half4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0);
    166.                 half4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
    167.  
    168.                 float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex);
    169.                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
    170.                 float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    171.    
    172.                 o.objSpaceNormal = v.normal;
    173.                 o.viewDir = mul(rotation, objSpaceViewDir);
    174.                 o.lightDir = mul(rotation, float3(_SunDir.xyz));
    175.  
    176.                 return o;
    177.             }
    178.  
    179.             sampler2D _Bump;
    180.             sampler2D _Foam;
    181.             half4 _SurfaceColorLod1;
    182.             half _FoamFactor;
    183.             half4 _WaterColorLod1;
    184.             half _WaterLod1Alpha;
    185.            
    186.             half4 frag (v2f i) : COLOR {
    187.                 half3 normViewDir = normalize(i.viewDir);
    188.                 half4 buv = half4(i.bumpTexCoord.x + _WaveOffset.x * 0.05, i.bumpTexCoord.y + _WaveOffset.y * 0.03, i.bumpTexCoord.x + _WaveOffset.z * 0.04, i.bumpTexCoord.y - _WaveOffset.w * 0.02);
    189.                 half2 buv2 = half2(i.bumpTexCoord.x - _WaveOffset.z * 0.05, i.bumpTexCoord.y - _WaveOffset.w * 0.05);
    190.                
    191.                 half3 tangentNormal0 = (tex2D(_Bump, buv.xy) * 2.0) - 1;
    192.                 half3 tangentNormal1 = (tex2D(_Bump, buv.zw) * 2.0) - 1;
    193.                 half3 tangentNormal = normalize(tangentNormal0 + tangentNormal1);
    194.  
    195.                 half4 result = half4(0, 0, 0, 1);
    196.                 half3 tex = tex2D(_WaterTex, buv2*2) * _WaterColorLod1;
    197.                
    198.                 float fresnelLookup = dot(tangentNormal, normViewDir);
    199.                 float bias = 0.06;
    200.                 float power = 4.0;
    201.                 float fresnelTerm = bias + (1.0-bias)*pow(1.0 - fresnelLookup, power);
    202.  
    203.                 float foamStrength = i.foamStrengthAndDistance.x * _FoamFactor;
    204.                 half4 foam = clamp(tex2D(_Foam, i.bumpTexCoord.xy * 1.0)  - 0.5, 0.0, 1.0) * foamStrength;
    205.  
    206.                 float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    207.                 float specular = pow(max(dot(halfVec, tangentNormal.xyz), 0.0), 250.0);
    208.                
    209.                 result.a = _WaterLod1Alpha;
    210.                 result.rgb = lerp(tex, _SurfaceColorLod1, fresnelTerm) + clamp(foam.r, 0.0, 1.0) + specular;
    211.                
    212.                 return result;
    213.             }
    214.             ENDCG
    215.            
    216.  
    217.         }
    218.     }
    219.     FallBack "Diffuse", 1
    220. }
    221.  
     
  16. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Here is a more optimized Ocean.cs script.

    It must be used with the shader above.

    - It updates in realtime the sun light color.

    - Enlarges by 5% the tile bounds to eliminate the random disappearance of tiles.

    - updates the meshes of tiles only when they are visible by the camera and adds around 15% speed increase.
     

    Attached Files:

    • Ocean.cs
      File size:
      32.2 KB
      Views:
      1,476
  17. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Nice !
    I updated the repo but I have not had time to test :(
     
  18. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    I optimized ocean.cs to run 4x to 6x faster!

    Will post later the script.
     
  19. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    :D
     
  20. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Alright. Here we go.

    i have made a lot of modifications on the Ocean.cs file.

    Besides the visibility checks, i am spreading the wave calculations among x frames and also added support for multi-threading.

    For devices that want vsync enabled a low number of spreading frames is recommended (3-4).
    If you go for higher frame rates then 5-7 is ok.

    You can disable multithreading by commenting out a preprocessor directive in the Ocean.cs file.

    I have optimized the Ocean.shader a bit more.

    Modified the Editor script to reflect and support the new additions and changes.

    panel.png

    Here are some profiler screenshots:

    Original:
    original.png

    Spread along frames only:
    spread.png

    Spread along frames + Multithreading:
    spread+threads.png



    More optimizations could be made on converting the exocortex lib to c++ native plugins.

    However the speed increase now opens more possibilities, especially for Desktop. The system runs very fast now so a lot more effects can be added on it.

    Download the needed files from the next post.
     
    Last edited: Dec 2, 2015
    Peter77 likes this.
  21. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Download the files from the attachments and replace. You should replace Ocean.cs, Ocean.shader and OceanGeneratorInspector.cs.
     

    Attached Files:

  22. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Hi Elias ! GOOD JOB !
    Working great on my computeur and mobile !

     
  23. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
  24. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Nice work guys, I'm impressed as heck with your amazing efforts.
     
    metaldc4life, twobob and elias_t like this.
  25. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Good to know that someone is taking notice!
    Laurent resurrected this for me. I had hit a wall in the past with this but now got inspired again.

    The huge speed increase should make it a very good solution for mobiles and desktops.
    Laurent, I am thinking on forking the project to my github account and try to add shorelines, underwater and other effects.

    Anyway here is one more update with significant speed increases and optimizations:


    SHADER:
    I have updated the shader for a better foam effect. However this adds one more texture fetch.

    old foam:
    oldfoam.jpg

    new foam:
    newfoam.jpg

    I have updated the LOD1 subshader to be consistent with LOD2 subshader.
    Removed unused stuff from shader.


    EDITOR:
    I have revamped the editor and made most of the variables to affect the ocean in realtime.
    Added variables in the editor that you could only change on the material.
    Added the ability to offset the position of far away lods (lod4, lod5). This is useful when you have large waves and you could see gaps in the horizon.

    (I am thinking of adding a load/save function of ocean presets.)

    new-editor.jpg


    OCEAN SCRIPT:

    - Skipping update every second tick of meshes belonging to lods>0. This gives an extra 5-10% speed increase.
    - General cleanup and avoiding unnecessary calculations.

    Download the files from the next post.
     
    Peter77 and hippocoder like this.
  26. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Here are the latest files:
     

    Attached Files:

  27. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    How do you guys propose to solve the whole "ocean is wasting cycles rendering under terrain" thing?

    Also how do you guys feel about calling this thread The Community Ocean Shader (Open Source) ? or similar.
     
    Last edited: Dec 2, 2015
  28. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    That's a hard task.

    The system could be modified so that around a terrain or a static mesh, special cutted ocean tiles will be used.
    Well, if you want to make some decent shorelines perhaps it should be done like this anyway...
     
  29. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Of course!

    Also, if anybody has any idea how we could cast shadows on this shader it would help.
    I have read a lot of posts on this matter and it seems it is an old issue with unity casting shadows on transparent stuff...
     
    Last edited: Dec 2, 2015
  30. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    No problem Elias ;)
     
    elias_t likes this.
  31. Torigas

    Torigas

    Joined:
    Jan 1, 2014
    Posts:
    63
    Awesome work guys!
     
  32. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    I am preparing the new version with lots of new improvements and functionality.
    But this time the changes require to set up my githup repo since it is becoming a different beast now.

    Later I will post the update here.
     
  33. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Ok. Here goes.

    I have created the github repo with the new version.

    https://github.com/eliasts/Ocean_Community_Next_Gen

    screenshot2.jpg

    Changes:

    - Some extra optimizations.

    - Ability to save and load presets of oceans. This will save you a lot of time.
    You can load the preset also on runtime, but some of the variables (like grid size) will not get updated for obvious reasons. Right now the directory for the presets is in the Assets/Ocean/Editor location
    . You can modify the editor script to your own needs.

    - Ability to have 1 or 2 extra lod materials/shaders for the far tiles. This will give around 15% extra speed increase.

    - Ability to choose the default LOD on the main shader.

    - Switch on runtime between high and low lod on the shader.

    - The shader has 3 lods and 1 extra with alpha transparency if you need it.

    - Shader rewritten for performance gains. (full SM2 support.)

    - uv scale of bump and foam maps stays consistent on all scales now.

    - Optimized the buoyancy script a bit and on the boat controller added a condition to raise the damp coefficient when idle.

    - The editor had an extra overhaul to reflect the new functionality. I added also some help buttons that explain the new functions.

    editor-new.jpg

    I will take a break for now.

    For the future:

    - Try to bake the fft and load it.
    - Try alternative fft function.

    - For mobiles add gerstner waves.
    - Add option for camera projected grid.

    But I will try to put back in the underwater effects, caustics and shore line.

    The shader as it is now is good for mobiles and desktops.
    But I will add a desktop variation to allow more calculations.

    Edit/update: I made the shaders faster by moving calculations from the fragment shader to the vertex shader. This leaves now room for more effects on the fragment shader.
    Also I fixed some issues on Android devices!

    Will update the repo soon.
     
    Last edited: Dec 5, 2015
    hopeful and Marco-Sperling like this.
  34. NullSignal

    NullSignal

    Joined:
    Sep 18, 2013
    Posts:
    45
    Is there a trick to getting the boat script to work with custom boats? I've got my ship set up the same way as the boat in the example scene (box collider, rigidbody, "engine" gameobject to provide thrust) but when I provide input, it just spins and pivots around the center(?) of my gameobject.

    BTW, if anyone super familiar with this script wants some paid work, message me.
     
  35. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Ok. I have updated the repo. https://github.com/eliasts/Ocean_Community_Next_Gen

    The shaders got one more overhaul, by removing yet more unnecessary calculations and by moving calculations from the fragment to the vertex shader.
    This gives room to squeeze in translucency and/or shadows on the hq shader lod.

    That solved some issues on my android device.

    In general compared to the old system my old XperiaS went from 12 fps to 30 fps.

    @carnivoris, send me please your boat so I can test it.
     
    FiveFingers and hopeful like this.
  36. Sabrina07198

    Sabrina07198

    Joined:
    Dec 6, 2015
    Posts:
    1
    I was wondering about the underwater system. really the project looks awesome both of yours elias_t and laurent.clave. I have downloaded both. 1st laurent's one had no fog effect but smoothing very nicely, 2ndly i have downloaded elias_t's one. it looks awesome and color looks great, also has fog but i think the rendering is slow maybe. Anyway keep up the good work both of you, Hats off to you guys.
     
  37. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Ouch!

    The version I have modified is about 500% faster. What you have witnessed is some jerkyness when updating the ocean >3-4 frames spread and having vsync enabled.

    Try to reduce the Calc waves every x frames value.

    Even without the frame spreading it is about 60% faster then the previous version.
     
    Last edited: Dec 6, 2015
    hopeful likes this.
  38. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Here comes another big update. https://github.com/eliasts/Ocean_Community_Next_Gen

    Untitled.jpg

    CHANGELOG:

    - Ability to skip renders of reflection/refraction. Since reflection and refraction are not easy for the eye to catch their changes, we can update them every x frames to gain performance.
    (this gives around 10-20% speed increase, but depends on the complexity of the rendered reflection/refraction layer.)

    -Preallocated LOD mesh buffers. This eliminates garbage generation and the kicking in of the GarbageCollector. Gives a small speed increase.

    -Added the ability to run the calculation of the waves using the FixedUpdate() function. This almost doubles the framerate compared to regular Update(), but disables the 'spread along frames' functionality."

    - Made the system WEBGL compliant. (Threads do not work in WEBGL for now.)

    - Yet another shader modification:
    --You can change the tiling of the foam and bump map now.
    --Corrected a glitch with foam/water bump animation.

    - Unhooked the boyancy.cs script from the boat controller. This was limiting the use of the boyancy script.
    - Optimized the boat controller script to avoid garbage generation.
    - Optimized the boyancy script:
    --to avoid garbage generation.
    --general optimizations to avoid GetComponent calls.
    --exposed y-offset and x/z slices in the inspector.
    --more importantly: added support for interpolating buoyancy among xx frames. This gives a much smoother movement.
    --with the optimizations the script has become around 20% faster.

    - Editor:
    --Ability to save the new additions (render reflection/refraction every xx frames, foam map tiling, bump map tiling)
    --Saves and loads the sun's rotation. Made loading of sun's rotation optional.
    --Sun direction vector gets updated in realtime now in the editor.

    -Demos: updated the demos to reflect realworld scales. The previous demo had exaggerated proportions.
    --Added bigger ships demonstrating how to set them up for buoyancy.

    -Optimized the GetWaterHeightAtLocation function to run 40% faster. (used for buoyancy ).

    -Allowed the spreading of the wave calculations to drop down to 2 frames. This should eliminate all jerkiness when vsync is on.

    -Restructured the thread balancing. This gave some good speed increasings depending on the frame spread selected. (10-25%).



    I am in the process to rewrite the multithreading methodology. This could give the extra speed needed to avoid spreading the jobs to more then 3 frames and so even with vsync the simulation will look smooth.
     
    red2blue, theANMATOR2b, SAOTA and 2 others like this.
  39. EDarkness

    EDarkness

    Joined:
    Feb 1, 2013
    Posts:
    506
    Someone recommended this and it looks pretty awesome so far. What's the performance like? Is it on par with Water 4? Can this be used for rivers, ponds, fountains, sewer water, etc? I've paid a lot for water that just isn't working for my project and I'm not really in looking to pay more for water that may or may not work. Not sure if I really need buoyancy, but just some nice looking water that the player can't really swim in is great.
     
  40. Torigas

    Torigas

    Joined:
    Jan 1, 2014
    Posts:
    63
    About the "update every X frames" thing.
    Is this something you can parallelize? I didn't have the time to delve into the whole thing yet but it does sound like you could maybe add a worker thread for that thing.
    Disregard this comment if you're pushing the whole thing to the GPU to run there.
     
  41. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    The performance compared to the previous iteration of the system has improved a lot.
    My goal is to make it as light as possible so I can add extra effects and functionality on it.
    As it is right now it can't be used for rivers and such. But I am thinking to allow the user to select the method so it could be a testbed of various water integrations.
     
    hopeful likes this.
  42. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    There is already multithreading in, but not as efficient as I would want it.
    That is because the wave calculations as they are now are not easy to parallelize.
    But I am working on a new method now that should give even more speed increase.
     
    hopeful likes this.
  43. EDarkness

    EDarkness

    Joined:
    Feb 1, 2013
    Posts:
    506
    That's good to know. Not sure if this will work for me, but I'll keep an eye on it. I need something that's mulit-purpose and I don't want to be dealing with many solutions just for water. Lightweight is good, though.
     
  44. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Free is even better thanks to hard working people who share :p
     
    twobob, EDarkness and hopeful like this.
  45. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    Hi all.

    I managed to find a sweet spot with the multithreading part.

    Now you get very smooth results with 3 frame spread job and vsync enabled.
    The more you lower the frames to spread the job the more the algorithm will use multithreading.

    https://github.com/eliasts/Ocean_Community_Next_Gen/

    Here is the changelog:

    08/12/2015

    • Restructured the multithreading code.
    • made the FFT plugin multithreading friendly.
    • The above optimizations give extra speed boost on low spread job frames. This gives now smooth results and very good performance with vsync and 3 frames job spread.

    • Had to fix the shader again because some previous hack made the seams of the tiles visible.

    • The ocean is now precalculated at the Start() function. This eliminates the annoyance having the boats jumping ugly at the beginning, because now they find their position on the sea.
     
    hopeful likes this.
  46. laurent-clave

    laurent-clave

    Joined:
    Jul 18, 2011
    Posts:
    280
    Nice Job Elias !!!!!
     
  47. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Awesome, really!
     
  48. b4c5p4c3

    b4c5p4c3

    Joined:
    Jan 4, 2013
    Posts:
    537
  49. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    09/12/2015 https://github.com/eliasts/Ocean_Community_Next_Gen

    • Improved the multithreading code a lot. Now the 2 frame spread gets a 14% speed increase and the 3 frame spread gets an 11% speed increase. The rest stays the same.
    • Fixed a bug where when using 2 shader lods the 1st lod material wouldn't get assigned.
    • Fixed one more issue with gaps being visible in far away tiles.
    • Revamped the editor and exposed the ability to alter the width of the foam trail produced by the boat and to specify if the lod meshes should skip frames to update.
    • Modified shaders to use floats instead of halfs because this causes precision artefacts on weak devices.
    • started adding code to improve the buoyancy.
    • optimized some math code.
    • added mask mesh to the fishing boat.
     
    Hormic, hopeful and runningbird like this.
  50. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,367
    I have been giving the buoyancy script some more attention. Now the choppy waves can influence floating objects.
    It will be modifiable of course by some factors.
    Also made it optional so the buoyancy script doesn't execute if the renderer is not visible.

    vid: