Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Converting Seascape GLSL shader into CG shader

Discussion in 'Shaders' started by Deleted User, Sep 25, 2016.

  1. Deleted User

    Deleted User

    Guest

    I try to convert water shader from

    https://www.shadertoy.com/view/Ms2SD1

    into Unity3d cg shader. After read tutorial from

    https://alastaira.wordpress.com/2015/08/07/unity-shadertoys-a-k-a-converting-glsl-shaders-to-cghlsl/

    I created necessary scripts and shader. I have no compiler warnings, but unfortunately, I have got black screen. Could someone give me a suggestion how to fix it ?

    Code (CSharp):
    1. // See https://www.shadertoy.com/view/4dl3zn
    2. // GLSL -> HLSL reference: https://msdn.microsoft.com/en-GB/library/windows/apps/dn166865.aspx
    3.  
    4. Shader "Custom/seascape" {
    5.  
    6.     SubShader {
    7.  
    8.         Pass {
    9.             CGPROGRAM
    10.  
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.  
    14.  
    15.                                     const int NUM_STEPS = 8;
    16. const float PI         = 3.1415;
    17. const float EPSILON    = 1e-3;
    18. float EPSILON_NRM    =  float(0.1   /1142);
    19.  
    20. // sea
    21. const int ITER_GEOMETRY = 3;
    22. const int ITER_FRAGMENT = 5;
    23. const float SEA_HEIGHT = 0.6;
    24. const float SEA_CHOPPY = 4.0;
    25. const float SEA_SPEED = 0.8;
    26. const float SEA_FREQ = 0.16;
    27. const float3 SEA_BASE = float3(0.1,0.19,0.22);
    28. const float3 SEA_WATER_COLOR = float3(0.8,0.9,0.6);
    29.  
    30. float SEA_TIME =1.0; //float(1.0 + _Time.y * 0.8);
    31. float2x2 octave_m = float2x2(1.6,1.2,-1.2,1.6);
    32.  
    33.             struct v2f{
    34.                 float4 position : SV_POSITION;
    35.             };
    36.  
    37.             v2f vert(float4 v:POSITION)  {
    38.                 v2f o;
    39.                 o.position = mul (UNITY_MATRIX_MVP, v);
    40.                 return o;
    41.             }
    42.  
    43.  
    44.  
    45.  
    46. // math
    47. float3x3 fromEuler(float3 ang) {
    48.     float2 a1 = float2(sin(ang.x),cos(ang.x));
    49.     float2 a2 = float2(sin(ang.y),cos(ang.y));
    50.     float2 a3 = float2(sin(ang.z),cos(ang.z));
    51.     float3x3 m;
    52.     m[0] = float3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
    53.     m[1] = float3(-a2.y*a1.x,a1.y*a2.y,a2.x);
    54.     m[2] = float3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
    55.     return m;
    56. }
    57. float hash( float2 p ) {
    58.     float h = dot(p,float2(127.1,311.7));  
    59.     return frac(sin(h)*43758.5453123);
    60. }
    61. float noise( in float2 p ) {
    62.     float2 i = floor( p );
    63.     float2 f = frac( p );  
    64.     float2 u = f*f*(3.0-2.0*f);
    65.     return -1.0+2.0*lerp( lerp( hash( i + float2(0.0,0.0) ),
    66.                      hash( i + float2(1.0,0.0) ), u.x),
    67.                 lerp( hash( i + float2(0.0,1.0) ),
    68.                      hash( i + float2(1.0,1.0) ), u.x), u.y);
    69. }
    70.  
    71. // lighting
    72. float diffuse(float3 n,float3 l,float p) {
    73.     return pow(dot(n,l) * 0.4 + 0.6,p);
    74. }
    75. float specular(float3 n,float3 l,float3 e,float s) {  
    76.     float nrm = (s + 8.0) / (3.1415 * 8.0);
    77.     return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
    78. }
    79.  
    80. // sky
    81. float3 getSkyColor(float3 e) {
    82.     e.y = max(e.y,0.0);
    83.     float3 ret;
    84.     ret.x = pow(1.0-e.y,2.0);
    85.     ret.y = 1.0-e.y;
    86.     ret.z = 0.6+(1.0-e.y)*0.4;
    87.     return ret;
    88. }
    89.  
    90. // sea
    91. float sea_octave(float2 uv, float choppy) {
    92.     uv += noise(uv);      
    93.    float2 wv = 1.0-abs(sin(uv));
    94.     float2 swv = abs(cos(uv));  
    95.     wv = lerp(wv,swv,wv);
    96.     return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
    97. }
    98.  
    99. float map(float3 p) {
    100.     float freq = SEA_FREQ;
    101.     float amp = SEA_HEIGHT;
    102.     float choppy = SEA_CHOPPY;
    103.     float2 uv = p.xz; uv.x *= 0.75;
    104.    
    105.     float d, h = 0.0;  
    106.     for(int i = 0; i < ITER_GEOMETRY; i++) {      
    107.         d = sea_octave((uv+SEA_TIME)*freq,choppy);
    108.         d += sea_octave((uv-SEA_TIME)*freq,choppy);
    109.         h += d * amp;      
    110.         uv =mul( octave_m,uv);
    111.         freq *= 1.9;
    112.         amp *= 0.22;
    113.         choppy = lerp(choppy,1.0,0.2);
    114.     }
    115.     return p.y - h;
    116. }
    117.  
    118. float map_detailed(float3 p) {
    119.     float freq = SEA_FREQ;
    120.     float amp = SEA_HEIGHT;
    121.     float choppy = SEA_CHOPPY;
    122.     float2 uv = p.xz; uv.x *= 0.75;
    123.    
    124.     float d, h = 0.0;  
    125.     for(int i = 0; i < ITER_FRAGMENT; i++) {      
    126.         d = sea_octave((uv+SEA_TIME)*freq,choppy);
    127.         d += sea_octave((uv-SEA_TIME)*freq,choppy);
    128.         h += d * amp;      
    129.         uv =mul( octave_m,uv); freq *= 1.9; amp *= 0.22;
    130.         choppy = lerp(choppy,1.0,0.2);
    131.     }
    132.     return p.y - h;
    133. }
    134.  
    135. float3 getSeaColor(float3 p, float3 n, float3 l, float3 eye, float3 dist) {
    136.     float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);
    137.     fresnel = pow(fresnel,3.0) * 0.65;
    138.        
    139.     float3 reflected = getSkyColor(reflect(eye,n));  
    140.     float3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12;
    141.    
    142.     float3 color = lerp(refracted,reflected,fresnel);
    143.    
    144.     float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
    145.     color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;
    146.    
    147.     color += float3(specular(n,l,eye,60.0),specular(n,l,eye,60.0),specular(n,l,eye,60.0));
    148.    
    149.     return color;
    150. }
    151.  
    152. // tracing
    153. float3 getNormal(float3 p, float eps) {
    154.     float3 n;
    155.     n.y = map_detailed(p);  
    156.     n.x = map_detailed(float3(p.x+eps,p.y,p.z)) - n.y;
    157.     n.z = map_detailed(float3(p.x,p.y,p.z+eps)) - n.y;
    158.     n.y = eps;
    159.     return normalize(n);
    160. }
    161.  
    162. float heightMapTracing(float3 ori, float3 dir, out float3 p) {
    163.     float tm = 0.0;
    164.     float tx = 1000.0;  
    165.     float hx = map(ori + dir * tx);
    166.     if(hx > 0.0) return tx;  
    167.     float hm = map(ori + dir * tm);  
    168.     float tmid = 0.0;
    169.     for(int i = 0; i < NUM_STEPS; i++) {
    170.         tmid = lerp(tm,tx, hm/(hm-hx));                  
    171.         p = ori + dir * tmid;                  
    172.         float hmid = map(p);
    173.         if(hmid < 0.0) {
    174.             tx = tmid;
    175.             hx = hmid;
    176.         } else {
    177.             tm = tmid;
    178.             hm = hmid;
    179.         }
    180.     }
    181.     return tmid;
    182. }
    183.  
    184.  
    185.             float4 frag(v2f i) : SV_Target {      
    186.  
    187.     float2 uv = i.position.xy / _ScreenParams.xy;
    188.     uv = uv * 2.0 - 1.0;
    189.     uv.x *= _ScreenParams.x / _ScreenParams.y;  
    190.     float time = _Time.y ;//* 0.3 + iMouse.x*0.01;
    191.        
    192.     // ray
    193.     float3 ang = float3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);  
    194.     float3 ori = float3(0.0,3.5,time*5.0);
    195.     float3 dir = normalize(float3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
    196.     dir = mul(normalize(dir) , fromEuler(ang));
    197.    
    198.     // tracing
    199.     float3 p;
    200.     heightMapTracing(ori,dir,p);
    201.     float3 dist = p - ori;
    202.     float3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
    203.     float3 light = normalize(float3(0.0,1.0,0.8));
    204.            
    205.     // color
    206.     float3 color = lerp(
    207.         getSkyColor(dir),
    208.         getSeaColor(p,n,light,dir,dist),
    209.         pow(smoothstep(0.0,-0.05,dir.y),0.3));
    210.        
    211.     // post
    212.      float4 fragColor = float4(pow(color,float3(0.75,0.75,0.75)), 1.0);
    213.      return fragColor;
    214.  
    215.  
    216.  
    217.             }
    218.  
    219.             ENDCG
    220.         }
    221.     }
    222. }
    223.  
     
  2. Deleted User

    Deleted User

    Guest

    Converting small shaders is quite easy, here 100 percent working example:
    source:
    https://www.shadertoy.com/view/4dsXD2

    and conversion made by me:
    Code (CSharp):
    1. Shader "Taylor_sin"
    2. {
    3.     Subshader
    4.     {
    5.         Pass
    6.         {
    7.             CGPROGRAM
    8.             #pragma vertex vertex_shader
    9.             #pragma fragment pixel_shader
    10.             #pragma target 3.0
    11.  
    12.             float4 vertex_shader (float4 local_vertex:POSITION):SV_POSITION
    13.             {
    14.                 return mul(UNITY_MATRIX_MVP,local_vertex);
    15.             }
    16.  
    17.             float taylor_sin(float x) {
    18.                 float x2 = x * x;  
    19.                 float xi = x2 * x;  
    20.                 x -= xi * 0.16666666666;
    21.                 xi *= x2; x += xi * 0.00833333333;
    22.                 xi *= x2; x -= xi * 0.00019841269;
    23.                 xi *= x2; x += xi * 0.00000275573;
    24.                 xi *= x2; x -= xi * 2.50521084e-8;
    25.                 xi *= x2; x += xi * 1.6059044e-10;
    26.                 xi *= x2; x -= xi * 7.6471635e-13;
    27.                 xi *= x2; x += xi * 2.8114572e-15;
    28.                 return x;
    29.             }
    30.  
    31.             float4 pixel_shader( float4 fragCoord : SV_POSITION ) : SV_TARGET
    32.             {  
    33.                 float2 uv = fragCoord.xy / _ScreenParams.xy;
    34.                 uv = (uv * 2.0 - 1.0);
    35.                 uv.x *= _ScreenParams.x / _ScreenParams.y;
    36.                 float2 fuv = uv * 10.0;
    37.                 float lum;
    38.                 if(uv.x < 0.0) lum = abs(sin(fuv.x) * sin(fuv.y));
    39.                 else lum = abs(taylor_sin(fuv.x) * taylor_sin(fuv.y));
    40.                 float4 fragColor = float4(lum,lum,lum,1.0);
    41.                 return fragColor;
    42.             }
    43.  
    44.             ENDCG
    45.         }
    46.     }
    47. }
     
  3. facemao3

    facemao3

    Joined:
    Feb 18, 2017
    Posts:
    1
    did you figure it out why ?
     
  4. Deleted User

    Deleted User

    Guest


    You can find here a few ready to use Shadertoy's shaders, and Seascape is included.
    In Unity3D editor, add 3D Object/Quad to Main Camera, then bind material with selected shader to the quad. Set quad position at (x=0 ; y=0; z=0.4;). Play.

    https://github.com/przemyslawzaworski/Unity3D-CG-programming
     
  5. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327
  6. EyezLee

    EyezLee

    Joined:
    Mar 25, 2018
    Posts:
    1
  7. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327
    Create new Material with ocean.shader, then add Ocean.cs script to Main Camera with material and main camera as public variables. Set camera position for example (0,10,0). Click Play (or append line {ExecuteInEditMode] to script to see result without pressing play).
    You don't need to add texture to material.