Search Unity

Simple Ocean For Flight Games (Unity Pro Only)

Discussion in 'Works In Progress - Archive' started by Rotorist, Jan 26, 2014.

  1. Rotorist

    Rotorist

    Joined:
    Jan 26, 2014
    Posts:
    11
    I'm making a flight game which involves a lot of flying over open oceans and islands, so I must make the ocean look good. I took Scrawk's Ocean Surface project and added following features:

    - Ocean color variation near shore lines
    - Shore foam
    - Cubemap reflection
    - Soft edge blend with terrain or mesh

    Scrawk's Ocean Surface project can be accessed here:

    http://scrawkblog.com/category/water/

    According to Scrawk, the features listed above are also part of his plan to accomplish, so until his version is ready, my little effort may be helpful for some. I would like to first obtain permission from Scrawk to publish my work as a free asset. And then I will upload this to the Asset Store.

    This asset is best for:
    - Flight simulator
    - Any game where the player is high above open ocean.

    This asset is NOT suitable for:
    - Any game where the player is near ocean shoreline (except when foam is disabled, it'll still look good)


    Screenshots from my game:







     
  2. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Im not sure where you got that but I am no longer working on this project and it will receive no more up dates. You are free to use or modify it if you wish and even put it on the asset store (for free). You will however need to sort out any remaining issues with it yourself.
     
    Last edited: Jan 31, 2014
  3. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    It's a great pity scrawk left this but it's nice to see people took the baton up - i cant exactly post the code for mine as it uses others work so should keep it private, but which iteration of the shader/generator did you use? I'm fairly hellbent on getting my tweaked whitecaps version to have coastal effects, so it get calmer at shores and underwater objects are shaded correctly, along with shoreline and decent reflections (refraction and blur is in)

    I can make a video if interested although theres one around but with dodgy shading - fixed later by editing the hdr function of of the original code
     
    Last edited: Jan 27, 2014
  4. Rotorist

    Rotorist

    Joined:
    Jan 26, 2014
    Posts:
    11
    My version is pretty simple and naive since I'm new to shader programming. I took Scrawk's most basic DX9 ocean without BRDF lighting or whitecap and added a simple camera depth check to calculate ocean color, foam color and alpha. It's done in surface shader not fragment shader like in BRDF lighting ocean or whitecap ocean. I have yet studied fragment shader and at this point I will leave the water part alone in order to move on with my project :) May visit back in the future, especially after I get a DX11 card :)
     
  5. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    Well as incomprehensible as I find some of it, if you take a fancy to the whitecaps version after getting a dx11 card (Which I think is brilliant) i could try and help out

    Worth noticing you can mix up surface shaders and vert/frag shaders in the same shader file, my ocean shader uses both
     
  6. shoeshine1984

    shoeshine1984

    Joined:
    Dec 3, 2013
    Posts:
    16
    So if you have all three in the same shader, then according to the flow, frag function will be run first and then surface function. Wouldn't the surface function overwrite whatever color manipulation you did in frag?
     
  7. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    Not so much overwrite but modify the result of the previous pass
     
  8. Rotorist

    Rotorist

    Joined:
    Jan 26, 2014
    Posts:
    11
    I will post my version of Scrawk's shader later and perhaps you can calculate the ocean lighting and base color (and reflection) in your frag shader and use my surface shader (adding IN.Color) to do the coastal effect.

    By the way, may I chat with you about an issue I have with terrain shader? :)
     
  9. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    Well, sure, although im no expert
     
  10. Rotorist

    Rotorist

    Joined:
    Jan 26, 2014
    Posts:
    11
    Thanks, actually I figured it out lol.

    So here's my version of OceanPro shader:

    Code (csharp):
    1.  
    2. Shader "Ocean/Pro/OceanShader"
    3. {
    4.     Properties
    5.     {
    6.         _SunPow("SunPow", float) = 256
    7.         _SeaColor("SeaColor", Color) = (1,1,1,1)
    8.         _ShoreSeaColor("ShoreSeaColor", Color) = (1,1,1,1)
    9.         _SkyBox("SkyBox", CUBE) = "" {}
    10.         _FoamTexture("Foam texture ", 2D) = "black" {}
    11.         _WaterOffset ("Water offset", Vector) = (0,0,0,0)
    12.     }
    13.    
    14.  
    15.  
    16.  
    17.     SubShader
    18.     {
    19.         Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    20.         LOD 200
    21.        
    22.         Blend SrcAlpha OneMinusSrcAlpha
    23.             ZTest LEqual
    24.             ZWrite Off
    25.             Cull Off
    26.            
    27.         CGPROGRAM
    28.         #pragma surface surf Lambert vertex:vert
    29.         #pragma target 3.0
    30.         #pragma glsl
    31.        
    32.         #include "UnityCG.cginc"
    33.  
    34.  
    35.         uniform sampler2D _FresnelLookUp, _Map0, _Map1, _Map2;
    36.         uniform float4 _GridSizes;
    37.         uniform float3 _SunColor, _SunDir;
    38.         uniform float _MaxLod, _LodFadeDist;
    39.        
    40.  
    41.         uniform sampler2D _CameraDepthTexture;
    42.         sampler2D _FoamTexture;
    43.         float3 _ShoreSeaColor;
    44.         float4 _WaterOffset;
    45.        
    46.        
    47.         float _SunPow;
    48.         float3 _SeaColor;
    49.         samplerCUBE _SkyBox;
    50.  
    51.         struct Input
    52.         {
    53.             float3 worldPos;
    54.             //float3 viewDir;
    55.             float3 worldRefl;
    56.             float4 screenPos;
    57.             float4 color : COLOR;
    58.             float2 uv_FoamTexture;
    59.             INTERNAL_DATA
    60.         };
    61.        
    62.         void vert(inout appdata_full v)
    63.         {
    64.             v.tangent = float4(1,0,0,1);
    65.            
    66.             float3 worldPos = mul(_Object2World, v.vertex).xyz;
    67.            
    68.             float dist = clamp(distance(_WorldSpaceCameraPos.xyz, worldPos) / _LodFadeDist, 0.0, 1.0);
    69.             float lod = _MaxLod * dist;
    70.            
    71.             float ht = 0.0;
    72.             ht += tex2Dlod(_Map0, float4(worldPos.xz/_GridSizes.x, 0, lod)).x;
    73.             ht += tex2Dlod(_Map0, float4(worldPos.xz/_GridSizes.y, 0, lod)).y;
    74.  
    75.             v.vertex.y += ht;
    76.         }
    77.        
    78.         float Fresnel(float3 V, float3 N)
    79.         {
    80.             float costhetai = abs(dot(V, N));
    81.             return tex2D(_FresnelLookUp, float2(costhetai, 0.0)).a * 0.7; //looks better scaled down a little?
    82.         }
    83.        
    84.         float3 Sun(float3 V, float3 N)
    85.         {
    86.             float3 H = normalize(V+_SunDir);
    87.             return _SunColor * pow(abs(dot(H,N)), _SunPow);
    88.         }
    89.  
    90.         void surf(Input IN, inout SurfaceOutput o)
    91.         {
    92.             float2 uv = IN.worldPos.xz;
    93.            
    94.             float2 slope = float2(0,0);
    95.             slope += tex2D(_Map1, uv/_GridSizes.x).xy;
    96.             slope += tex2D(_Map1, uv/_GridSizes.y).zw;
    97.             slope += tex2D(_Map2, uv/_GridSizes.z).xy;
    98.             slope += tex2D(_Map2, uv/_GridSizes.w).zw;
    99.            
    100.             float3 N = normalize(float3(-slope.x, 2.0, -slope.y)); //shallow normal
    101.             float3 N2 = normalize(float3(-slope.x, 0.7, -slope.y)); //sharp normal
    102.            
    103.             float3 V = normalize(_WorldSpaceCameraPos-IN.worldPos);
    104.            
    105.             float fresnel = Fresnel(V, N);
    106.            
    107.            
    108.  
    109.            
    110.             fixed testZ = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)));
    111.             testZ = LinearEyeDepth(testZ) - IN.screenPos.w;
    112.            
    113.  
    114.            
    115.             fixed coastal = (1-IN.color.a) * 0.35f;
    116.             coastal *= coastal;
    117.            
    118.            
    119.            
    120.             o.Normal = N.xzy;//this is tangent space?
    121.             float4 skyColor = texCUBE(_SkyBox, WorldReflectionVector(IN, o.Normal));//*float3(-1,1,0.5f)).rgb;//flip x?
    122.            
    123.             float dist = distance(_WorldSpaceCameraPos, IN.worldPos);
    124.             float seaColorFactor;
    125.            
    126.  
    127.             seaColorFactor = 1- saturate(testZ * 0.02f);
    128.  
    129.             float3 waterColor = seaColorFactor * _ShoreSeaColor + (1 - seaColorFactor) * _SeaColor;
    130.            
    131.            
    132.            
    133.            
    134.             float edgeBlendHigh = 0.25f;
    135.             float edgeBlendHigh2 = 0.35f;
    136.             float edgeBlendLow = 0.1f;
    137.             float edgeBlend = edgeBlendLow;
    138.            
    139.             if(dist < 300  dist > 50)
    140.             {
    141.                 edgeBlend = edgeBlendLow + (300 - dist)/250f * (edgeBlendHigh - edgeBlendLow);
    142.             }
    143.             else if(dist <= 50)
    144.             {
    145.                 edgeBlend = edgeBlendHigh + (50 - dist)/50f * (edgeBlendHigh2 - edgeBlendHigh);
    146.             }
    147.            
    148.  
    149.             float foamColorFactor = 1 - saturate(testZ * edgeBlend);
    150.             if(foamColorFactor < 0.3)
    151.             {
    152.                 foamColorFactor *= 2;
    153.             }
    154.             else
    155.             {
    156.                 foamColorFactor = 0;
    157.             }
    158.            
    159.             fixed2 foampos1 = IN.worldPos.xz;
    160.             fixed2 foampos2 = IN.worldPos.xz;
    161.            
    162.             fixed4 foam = lerp(
    163.               tex2D( _FoamTexture, foampos1 * 0.010f ),
    164.               tex2D( _FoamTexture, foampos2 * 0.050f ),
    165.               clamp( sin( _Time.z * 0.5f + (IN.worldPos.x + IN.worldPos.z) * 0.1f ) * 0.5f + 0.5f, 0, 1 )
    166.               ) * 2f * foamColorFactor;
    167.            
    168.             waterColor = foamColorFactor * foam + (1 - foamColorFactor) * waterColor;
    169.            
    170.             o.Albedo = lerp(waterColor, skyColor, fresnel/1.5f) + Sun(V,N2);
    171.             o.Alpha = lerp(testZ * 0.15f + 0.02f, 1, coastal);
    172.            
    173.         }
    174.         ENDCG
    175.     }
    176.     FallBack "Diffuse"
    177. }
    178.  
    179.  
    180.  
     
  11. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    I may try using parts of it soon, a bunch of my shader seperates the illumination from sky and the irradiance for fancy visual effects so cant use verbatim, the whitecaps going on top of that for course, cheers for that though