Search Unity

Elevated shader in Unity3D.

Discussion in 'Shaders' started by Przemyslaw_Zaworski, Aug 20, 2017.

  1. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Do you remember famous 4 KB demo called Elevated from 2009 year ?
    Now you can, thanks to source code shared from https://www.shadertoy.com/view/MdX3Rr ,
    free flythrough over procedural generated mountains directly in Unity3D !
    In Unity3D editor, add quad to Main Camera. Set quad position (0.0;0.0;0.4) and camera position(0,100,0). Bind material with shader to the quad. Add fly script to the camera. Play.
    Fly script:
    https://forum.unity3d.com/threads/fly-cam-simple-cam-script.67042/
    Shader source:
    https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/elevated.shader




    Code (CSharp):
    1. //source : https://www.shadertoy.com/view/MdX3Rr
    2.  
    3. Shader "Elevated"
    4. {
    5.     Subshader
    6.     {
    7.         Pass
    8.         {
    9.             CGPROGRAM
    10.             #pragma vertex vertex_shader
    11.             #pragma fragment pixel_shader
    12.             #pragma target 4.0
    13.  
    14.             struct custom_type
    15.             {
    16.                 float4 screen_vertex : SV_POSITION;
    17.                 float3 world_vertex : TEXCOORD1;
    18.             };
    19.  
    20.             #define SC (5.0)
    21.  
    22.             float rand(float2 n)
    23.             {
    24.                 return frac(sin(dot(n, float2(12.9898, 4.1414))) * 43758.5453);
    25.             }
    26.  
    27.             float3 noised(float2 x )
    28.             {
    29.                 float2 f = frac(x);
    30.                 float2 u = f*f*(3.0-2.0*f);
    31.                 float2 p = floor(x);
    32.                 float a = rand (p + float2(0.0,0.0));
    33.                 float b = rand (p + float2(1.0,0.0));
    34.                 float c = rand (p + float2(0.0,1.0));
    35.                 float d = rand (p + float2(1.0,1.0));              
    36.                 return float3(a+(b-a)*u.x+(c-a)*u.y+(a-b-c+d)*u.x*u.y,
    37.                     6.0*f*(1.0-f)*(float2(b-a,c-a)+(a-b-c+d)*u.yx));
    38.             }
    39.  
    40.             static const float2x2 m2 = float2x2(0.8,-0.6,0.6,0.8);
    41.  
    42.             float terrainH( float2 x )
    43.             {
    44.                 float2  p = x*0.003/SC;
    45.                 float a = 0.0;
    46.                 float b = 1.0;
    47.                 float2  d = float2(0.0,0.0);
    48.                 for( int i=0; i<15; i++ )
    49.                 {
    50.                     float3 n = noised(p);
    51.                     d += n.yz;
    52.                     a += b*n.x/(1.0+dot(d,d));
    53.                     b *= 0.5;
    54.                     p = p*2.0;
    55.                     p = mul(p,m2);
    56.                 }
    57.                 return SC*120.0*a;
    58.             }
    59.  
    60.             float terrainM( float2 x )
    61.             {
    62.                 float2  p = x*0.003/SC;
    63.                 float a = 0.0;
    64.                 float b = 1.0;
    65.                 float2 d = float2(0.0,0.0);
    66.                 for( int i=0; i<9; i++ )
    67.                 {
    68.                     float3 n = noised(p);
    69.                     d += n.yz;
    70.                     a += b*n.x/(1.0+dot(d,d));
    71.                     b *= 0.5;
    72.                     p = p*2.0;
    73.                     p = mul(p,m2);
    74.                 }
    75.                 return SC*120.0*a;
    76.             }
    77.  
    78.             float terrainL( float2 x )
    79.             {
    80.                 float2  p = x*0.003/SC;
    81.                 float a = 0.0;
    82.                 float b = 1.0;
    83.                 float2  d = float2(0.0,0.0);
    84.                 for( int i=0; i<3; i++ )
    85.                 {
    86.                     float3 n = noised(p);
    87.                     d += n.yz;
    88.                     a += b*n.x/(1.0+dot(d,d));
    89.                     b *= 0.5;
    90.                     p = p*2.0;
    91.                     p = mul(p,m2);
    92.                 }
    93.                 return SC*120.0*a;
    94.             }
    95.  
    96.             float intersect(float3 ro,float3 rd,float tmin,float tmax )
    97.             {
    98.                 float t = tmin;
    99.                 for( int i=0; i<256; i++ )
    100.                 {
    101.                     float3 pos = ro + t*rd;
    102.                     float h = pos.y - terrainM( pos.xz );
    103.                     if( h<(0.002*t) || t>tmax ) break;
    104.                     t += 0.3*h;
    105.                 }
    106.                 return t;
    107.             }
    108.  
    109.             float softShadow(float3 ro,float3 rd )
    110.             {
    111.                 float res = 1.0;
    112.                 float t = 0.001;
    113.                 for( int i=0; i<80; i++ )
    114.                 {
    115.                     float3  p = ro + t*rd;
    116.                     float h = p.y - terrainM( p.xz );
    117.                     res = min( res, 16.0*h/t );
    118.                     t += h;
    119.                     if(res<0.001||p.y>(SC*200.0)) break;
    120.                 }
    121.                 return saturate(res);
    122.             }
    123.  
    124.             float3 calcNormal(float3 pos, float t )
    125.             {
    126.                 float2 eps = float2( 0.002*t, 0.0 );
    127.                 return normalize( float3( terrainH(pos.xz-eps.xy) - terrainH(pos.xz+eps.xy),
    128.                     2.0*eps.x,terrainH(pos.xz-eps.yx) - terrainH(pos.xz+eps.yx) ) );
    129.             }
    130.  
    131.             float fbm( float2 p )
    132.             {
    133.                 float f = 0.0;
    134.                 f += 0.5000*noised(p).x; p = p*2.02; p = mul(p,m2);
    135.                 f += 0.2500*noised(p).x; p = p*2.03; p = mul(p,m2);
    136.                 f += 0.1250*noised(p).x; p = p*2.01; p = mul(p,m2);
    137.                 f += 0.0625*noised(p).x;
    138.                 return f/0.9375;
    139.             }
    140.  
    141.             static const float kMaxT = 5000.0*SC;
    142.  
    143.             float4 render( in float3 ro, in float3 rd )
    144.             {
    145.                 float3 light1 = normalize(float3(-0.8,0.4,-0.3));
    146.                 float tmin = 0.5;
    147.                 float tmax = kMaxT;
    148.                 float sundot = clamp(dot(rd,light1),0.0,1.0);
    149.                 float3 col;
    150.                 float t = intersect( ro, rd, tmin, tmax );
    151.                 if( t>tmax)
    152.                 {  
    153.                     col = float3(0.2,0.5,0.85)*1.1 - rd.y*rd.y*0.5;
    154.                     col = lerp( col, 0.85*float3(0.7,0.75,0.85), pow( 1.0-max(rd.y,0.0), 4.0 ) );
    155.                     col += 0.25*float3(1.0,0.7,0.4)*pow( sundot,5.0 );
    156.                     col += 0.25*float3(1.0,0.8,0.6)*pow( sundot,64.0 );
    157.                     col += 0.2*float3(1.0,0.8,0.6)*pow( sundot,512.0 );
    158.                     float2 sc = ro.xz + rd.xz*(SC*1000.0-ro.y)/rd.y;
    159.                     col = lerp( col, float3(1.0,0.95,1.0), 0.5*smoothstep(0.5,0.8,fbm(0.0005*sc/SC)) );
    160.                     col = lerp( col, 0.68*float3(0.4,0.65,1.0), pow( 1.0-max(rd.y,0.0), 16.0 ) );
    161.                     t = -1.0;
    162.                 }
    163.                 else
    164.                 {
    165.                     float3 pos = ro + t*rd;
    166.                     float3 nor = calcNormal( pos, t );
    167.                     float3 ref = reflect( rd, nor );
    168.                     float fre = clamp( 1.0+dot(rd,nor), 0.0, 1.0 );
    169.                     float r = noised((7.0/SC)*pos.xz/256.0 ).x;
    170.                     col = (r*0.25+0.75)*0.9*lerp( float3(0.08,0.05,0.03), float3(0.10,0.09,0.08),
    171.                         noised(0.00007*float2(pos.x,pos.y*48.0)/SC).x );
    172.                     col = lerp( col, 0.20*float3(0.45,.30,0.15)*(0.50+0.50*r),smoothstep(0.70,0.9,nor.y) );
    173.                     col = lerp( col, 0.15*float3(0.30,.30,0.10)*(0.25+0.75*r),smoothstep(0.95,1.0,nor.y) );
    174.                     float h = smoothstep(55.0,80.0,pos.y/SC + 25.0*fbm(0.01*pos.xz/SC) );
    175.                     float e = smoothstep(1.0-0.5*h,1.0-0.1*h,nor.y);
    176.                     float o = 0.3 + 0.7*smoothstep(0.0,0.1,nor.x+h*h);
    177.                     float s = h*e*o;
    178.                     col = lerp( col, 0.29*float3(0.62,0.65,0.7), smoothstep( 0.1, 0.9, s ) );      
    179.                     float amb = clamp(0.5+0.5*nor.y,0.0,1.0);
    180.                     float dif = clamp( dot( light1, nor ), 0.0, 1.0 );
    181.                     float bac = clamp( 0.2 + 0.8*dot( normalize( float3(-light1.x, 0.0, light1.z ) ), nor ), 0.0, 1.0 );
    182.                     float sh = 1.0; if( dif>=0.0001 ) sh = softShadow(pos+light1*SC*0.05,light1);      
    183.                     float3 lin  = float3(0.0,0.0,0.0);
    184.                     lin += dif*float3(7.00,5.00,3.00)*1.3*float3( sh, sh*sh*0.5+0.5*sh, sh*sh*0.8+0.2*sh );
    185.                     lin += amb*float3(0.40,0.60,0.80)*1.2;
    186.                     lin += bac*float3(0.40,0.50,0.60);
    187.                     col *= lin;      
    188.                     col += s*0.1*pow(fre,4.0)*float3(7.0,5.0,3.0)*sh * pow( clamp(dot(light1,ref), 0.0, 1.0),16.0);
    189.                     col += s*0.1*pow(fre,4.0)*float3(0.4,0.5,0.6)*smoothstep(0.0,0.6,ref.y);
    190.                     float fo = 1.0-exp(-pow(0.001*t/SC,1.5) );
    191.                     float3 fco = 0.65*float3(0.4,0.65,1.0);// + 0.1*float3(1.0,0.8,0.5)*pow( sundot, 4.0 );
    192.                     col = lerp( col, fco, fo );
    193.  
    194.                 }
    195.                 col += 0.3*float3(1.0,0.7,0.3)*pow( sundot, 8.0 );
    196.                 col = sqrt(col);
    197.                 return float4( col, 1.0 );
    198.             }  
    199.      
    200.             custom_type vertex_shader (float4 vertex : POSITION)
    201.             {
    202.                 custom_type vs;
    203.                 vs.screen_vertex = UnityObjectToClipPos (vertex);
    204.                 vs.world_vertex = mul (unity_ObjectToWorld, vertex);
    205.                 return vs;
    206.             }
    207.  
    208.             float4 pixel_shader (custom_type ps ) : SV_TARGET
    209.             {
    210.                 float3 worldPosition = ps.world_vertex;
    211.                 float3 viewDirection = normalize(ps.world_vertex - _WorldSpaceCameraPos.xyz);
    212.                 return render (worldPosition,viewDirection);
    213.             }
    214.  
    215.             ENDCG
    216.  
    217.         }
    218.     }
    219. }
     
    mgear likes this.
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Ugly shader, beautiful result. A good thing to note is that this shader renders everything you see here. Including the sky, clouds, sun and fog. Not just the terrain. And it uses no textures. Just over 200 lines of code completely generate that scene.
     
  3. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    @jvo3dc
    "ugly shader", what do you mean ? :)
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    I mean ugly code. Very non-descriptive names for the variables.
     
  5. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    @Przemyslaw_Zaworski

    Firstly thank you for the code
    I'm just starting off with shaders
    I tried using the code but I'm getting an undeclared identifier UnityObjectToClipPos
    Could you help me out with this
     
  6. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Could you tell which version of Unity engine do you use ?
     
  7. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    Thanks for getting back,
    I am using the Unity 2017.2.1f1 version
    I floated a value
    inline float4 UnityObjectToClipPos( in float3 pos )
    and solved the first issue

    now the shader error is
    redefinition of float for the line
    float rand(float2 n)
    {
    return frac(sin(dot(n, float2(12.9898, 4.1414))) * 43758.5453);
    }
     
  8. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    Thank you so much. I like a fool was tring
     
  9. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    trying to run the shader on a force-opengl mode. Its working fine now.
     
  10. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Original code from #1 post works great on Unity 2018.2.14f1 (new project with 3D template) in DX11 mode
     
  11. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    @Przemyslaw_Zaworski

    Sorry to be bothering you often
    But could you help me to convert this shader https://www.shadertoy.com/view/4ttSWf
    Its from the same author and of what I have read something on similar lines.
    Would greatly appreciate your help as I'm trying to explore the use of shaderrtoy shaders as 3D game environments
     
  12. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
  13. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    I really appreciate your help, thanks. I will look through the files, see the code and see how you have converted each of them. That is an impressive list of shaders you have there. If I still cant do it then I shall consult with you. Thanks once again.
     
  14. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    @Przemyslaw_Zaworski

    Hello, I have tried my best to convert the GLSL code these past few months but haven't been successful. I looked at all the tutorials too but I guess my very limited knowledge is evident. This shader https://www.shadertoy.com/view/MdlGW7 by the same author has the same GLSL code as the one you converted(Elevated) but the results are so different. Would you please help me convert it and understand the process?
     
  15. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    This is multipass, so converting it may be not easy. But we can, in first try, remove motion blur and convert shader to single pass form, like this:
    Code (CSharp):
    1. // Created by inigo quilez - iq/2013
    2. // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
    3.  
    4. float noise( in vec3 x )
    5. {
    6.     vec3 p = floor(x);
    7.     vec3 f = fract(x);
    8.  
    9.     float a = textureLod( iChannel0, x.xy/256.0 + (p.z+0.0)*120.7123, 0.0 ).x;
    10.     float b = textureLod( iChannel0, x.xy/256.0 + (p.z+1.0)*120.7123, 0.0 ).x;
    11.     return mix( a, b, f.z );
    12. }
    13.  
    14.  
    15. const mat3 m = mat3( 0.00,  0.80,  0.60,
    16.                     -0.80,  0.36, -0.48,
    17.                     -0.60, -0.48,  0.64 );
    18.  
    19. float fbm( vec3 p )
    20. {
    21.     float f;
    22.     f  = 0.5000*noise( p ); p = m*p*2.02;
    23.     f += 0.2500*noise( p ); p = m*p*2.03;
    24.     f += 0.1250*noise( p ); p = m*p*2.01;
    25.     f += 0.0625*noise( p );
    26.     return f;
    27. }
    28.  
    29. float envelope( vec3 p )
    30. {
    31.     float isLake = 1.0-smoothstep( 0.62, 0.72, textureLod( iChannel0, 0.001*p.zx, 0.0).x );
    32.     return 0.1 + isLake*0.9*textureLod( iChannel1, 0.01*p.xz, 0.0 ).x;
    33. }
    34.  
    35. float mapTerrain( in vec3 pos )
    36. {
    37.     return pos.y - envelope(pos);
    38. }
    39.  
    40. float raymarchTerrain( in vec3 ro, in vec3 rd )
    41. {
    42.     float maxd = 50.0;
    43.     float precis = 0.001;
    44.     float h = 1.0;
    45.     float t = 0.0;
    46.     for( int i=0; i<80; i++ )
    47.     {
    48.         if( abs(h)<precis||t>maxd ) break;
    49.         t += h;
    50.         h = mapTerrain( ro+rd*t );
    51.     }
    52.  
    53.     if( t>maxd ) t=-1.0;
    54.     return t;
    55. }
    56.  
    57. vec3 lig = normalize( vec3(0.7,0.4,0.2) );
    58.  
    59. vec3 calcNormal( in vec3 pos )
    60. {
    61.     vec3 eps = vec3(0.02,0.0,0.0);
    62.     return normalize( vec3(
    63.            mapTerrain(pos+eps.xyy) - mapTerrain(pos-eps.xyy),
    64.            0.5*2.0*eps.x,
    65.            mapTerrain(pos+eps.yyx) - mapTerrain(pos-eps.yyx) ) );
    66.  
    67. }
    68.  
    69. vec4 mapTrees( in vec3 pos, in vec3 rd )
    70. {
    71.     vec3  col = vec3(0.0);  
    72.     float den = 1.0;
    73.  
    74.     float kklake = textureLod( iChannel0, 0.001*pos.zx, 0.0).x;
    75.     float isLake = smoothstep( 0.7, 0.71, kklake );
    76.    
    77.     if( pos.y>1.0 || pos.y<0.0 )
    78.     {
    79.         den = 0.0;
    80.     }
    81.     else
    82.     {
    83.        
    84.         float h = pos.y;
    85.         float e = envelope( pos );
    86.         float r = clamp(h/e,0.0,1.0);
    87.        
    88.         den = smoothstep( r, 1.0, textureLod(iChannel0, pos.xz*0.15, 0.0).x );
    89.        
    90.         den *= 1.0-0.95*clamp( (r-0.75)/(1.0-0.75) ,0.0,1.0);
    91.        
    92.         float id = textureLod( iChannel0, pos.xz, 0.0).x;
    93.         float oc = pow( r, 2.0 );
    94.  
    95.         vec3  nor = calcNormal( pos );
    96.         vec3  dif = vec3(1.0)*clamp( dot( nor, lig ), 0.0, 1.0 );
    97.         float amb = 0.5 + 0.5*nor.y;
    98.        
    99.         float w = (2.8-pos.y)/lig.y;
    100.         float c = fbm( (pos+w*lig)*0.35 );
    101.         c = smoothstep( 0.38, 0.6, c );
    102.         dif *= pow( vec3(c), vec3(0.8, 1.0, 1.5 ) );
    103.            
    104.         vec3  brdf = 1.7*vec3(1.5,1.0,0.8)*dif*(0.1+0.9*oc) + 1.3*amb*vec3(0.1,0.15,0.2)*oc;
    105.  
    106.         vec3 mate = 0.6*vec3(0.5,0.5,0.1);
    107.         mate += 0.3*textureLod( iChannel1, 0.1*pos.xz, 0.0 ).zyx;
    108.        
    109.         col = brdf * mate;
    110.  
    111.         den *= 1.0-isLake;
    112.     }
    113.  
    114.     return vec4( col, den );
    115. }
    116.  
    117.  
    118. vec4 raymarchTrees( in vec3 ro, in vec3 rd, float tmax, vec3 bgcol, out float resT )
    119. {
    120.     vec4 sum = vec4(0.0);
    121.     float t = tmax;
    122.     for( int i=0; i<512; i++ )
    123.     {
    124.         vec3 pos = ro + t*rd;
    125.         if( sum.a>0.99 || pos.y<0.0  || t>20.0 ) break;
    126.        
    127.         vec4 col = mapTrees( pos, rd );
    128.  
    129.         col.xyz = mix( col.xyz, bgcol, 1.0-exp(-0.0018*t*t) );
    130.        
    131.         col.rgb *= col.a;
    132.  
    133.         sum = sum + col*(1.0 - sum.a);  
    134.        
    135.         t += 0.0035*t;
    136.     }
    137.    
    138.     resT = t;
    139.  
    140.     return clamp( sum, 0.0, 1.0 );
    141. }
    142.  
    143. vec4 mapClouds( in vec3 p )
    144. {
    145.     float d = 1.0-0.3*abs(2.8 - p.y);
    146.     d -= 1.6 * fbm( p*0.35 );
    147.  
    148.     d = clamp( d, 0.0, 1.0 );
    149.    
    150.     vec4 res = vec4( d );
    151.  
    152.     res.xyz = mix( 0.8*vec3(1.0,0.95,0.8), 0.2*vec3(0.6,0.6,0.6), res.x );
    153.     res.xyz *= 0.65;
    154.    
    155.     return res;
    156. }
    157.  
    158.  
    159. vec4 raymarchClouds( in vec3 ro, in vec3 rd, in vec3 bcol, float tmax, out float rays, ivec2 px )
    160. {
    161.     vec4 sum = vec4(0, 0, 0, 0);
    162.     rays = 0.0;
    163.    
    164.     float sun = clamp( dot(rd,lig), 0.0, 1.0 );
    165.     float t = 0.1*texelFetch( iChannel0, px&ivec2(255), 0 ).x;
    166.     for(int i=0; i<64; i++)
    167.     {
    168.         if( sum.w>0.99 || t>tmax ) break;
    169.         vec3 pos = ro + t*rd;
    170.         vec4 col = mapClouds( pos );
    171.  
    172.         float dt = max(0.1,0.05*t);
    173.         float h = (2.8-pos.y)/lig.y;
    174.         float c = fbm( (pos + lig*h)*0.35 );
    175.         //kk += 0.05*dt*(smoothstep( 0.38, 0.6, c ))*(1.0-col.a);
    176.         rays += 0.02*(smoothstep( 0.38, 0.6, c ))*(1.0-col.a)*(1.0-smoothstep(2.75,2.8,pos.y));
    177.    
    178.        
    179.         col.xyz *= vec3(0.4,0.52,0.6);
    180.        
    181.         col.xyz += vec3(1.0,0.7,0.4)*0.4*pow( sun, 6.0 )*(1.0-col.w);
    182.        
    183.         col.xyz = mix( col.xyz, bcol, 1.0-exp(-0.0018*t*t) );
    184.        
    185.         col.a *= 0.5;
    186.         col.rgb *= col.a;
    187.  
    188.         sum = sum + col*(1.0 - sum.a);  
    189.  
    190.         t += dt;//max(0.1,0.05*t);
    191.     }
    192.     rays = clamp( rays, 0.0, 1.0 );
    193.  
    194.     return clamp( sum, 0.0, 1.0 );
    195. }
    196.  
    197. vec3 path( float time )
    198. {
    199.     return vec3( 32.0*cos(0.2+0.75*.1*time*1.5), 1.2, 32.0*sin(0.1+0.75*0.11*time*1.5) );
    200. }
    201.  
    202. mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
    203. {
    204.     vec3 cw = normalize(ta-ro);
    205.     vec3 cp = vec3(sin(cr), cos(cr),0.0);
    206.     vec3 cu = normalize( cross(cw,cp) );
    207.     vec3 cv = normalize( cross(cu,cw) );
    208.     return mat3( cu, cv, cw );
    209. }
    210.  
    211. void moveCamera( float time, out vec3 oRo, out vec3 oTa, out float oCr, out float oFl )
    212. {
    213.     // camera  
    214.     oRo = path( time );
    215.     oTa = path( time+1.0 );
    216.     oTa.y *= 0.2;
    217.     oCr = 0.3*cos(0.07*time);
    218.     oFl = 1.75;
    219. }
    220.  
    221. void mainImage( out vec4 fragColor, in vec2 fragCoord )
    222. {
    223.     vec2 q = fragCoord.xy / iResolution.xy;
    224.     vec2 p = -1.0 + 2.0*q;
    225.     p.x *= iResolution.x / iResolution.y;
    226.    
    227.     float time = 23.5+iTime;
    228.    
    229.     // camera  
    230.     vec3 ro, ta;
    231.     float roll, fl;
    232.     moveCamera( time, ro, ta, roll, fl );
    233.        
    234.     // camera tx
    235.     mat3 cam = setCamera( ro, ta, roll );
    236.  
    237.     // ray direction
    238.     vec3 rd = normalize( cam * vec3(p.xy,fl) );
    239.  
    240.     // sky    
    241.     vec3 col = vec3(0.84,0.95,1.0)*0.77 - rd.y*0.6;
    242.     col *= 0.75;
    243.     float sun = clamp( dot(rd,lig), 0.0, 1.0 );
    244.     col += vec3(1.0,0.7,0.3)*0.3*pow( sun, 6.0 );
    245.     vec3 bcol = col;
    246.  
    247.     // lakes
    248.     float gt = (0.0-ro.y)/rd.y;
    249.     if( gt>0.0 )
    250.     {
    251.         vec3 pos = ro + rd*gt;
    252.  
    253.         vec3 nor = vec3(0.0,1.0,0.0);
    254.         nor.xz  = 0.10*(-1.0 + 2.0*texture( iChannel3, 1.5*pos.xz ).xz);
    255.         nor.xz += 0.15*(-1.0 + 2.0*texture( iChannel3, 3.2*pos.xz ).xz);
    256.         nor.xz += 0.20*(-1.0 + 2.0*texture( iChannel3, 6.0*pos.xz ).xz);
    257.     nor = normalize(nor);
    258.  
    259.         vec3 ref = reflect( rd, nor );
    260.         vec3 sref = reflect( rd, vec3(0.0,1.0,0.0) );
    261.         float sunr = clamp( dot(ref,lig), 0.0, 1.0 );
    262.  
    263.         float kklake = texture( iChannel0, 0.001*pos.zx).x;
    264.         col = vec3(0.1,0.1,0.0);
    265.         vec3 lcol = vec3(0.2,0.5,0.7);
    266.         col = mix( lcol, 1.1*vec3(0.2,0.6,0.7), 1.0-smoothstep(0.7,0.81,kklake) );
    267.        
    268.         col *= 0.12;
    269.  
    270.         float fre = 1.0 - max(sref.y,0.0);
    271.         col += 0.8*vec3(1.0,0.9,0.8)*pow( sunr, 64.0 )*pow(fre,1.0);
    272.         col += 0.5*vec3(1.0,0.9,0.8)*pow( fre, 10.0 );
    273.  
    274.         float h = (2.8-pos.y)/lig.y;
    275.         float c = fbm( (pos+h*lig)*0.35 );
    276.         col *= 0.4 + 0.6*smoothstep( 0.38, 0.6, c );
    277.  
    278.         col *= smoothstep(0.7,0.701,kklake);
    279.  
    280.         col.xyz = mix( col.xyz, bcol, 1.0-exp(-0.0018*gt*gt) );
    281.     }
    282.  
    283.  
    284.     // terrain  
    285.     float t = raymarchTerrain(ro, rd);
    286.     if( t>0.0 )
    287.     {
    288.         // trees      
    289.         float ot;
    290.         vec4 res = raymarchTrees( ro, rd, t, bcol, ot );
    291.         t = ot;
    292.         col = col*(1.0-res.w) + res.xyz;
    293.     }
    294.  
    295.     // sun glow
    296.     col += vec3(1.0,0.5,0.2)*0.35*pow( sun, 3.0 );
    297.  
    298.     float rays = 0.0;
    299.     // clouds  
    300.     {
    301.     if( t<0.0 ) t=600.0;
    302.     vec4 res = raymarchClouds( ro, rd, bcol, t, rays, ivec2(fragCoord) );
    303.     col = col*(1.0-res.w) + res.xyz;
    304.     }
    305.  
    306.     col += (1.0-0.8*col)*rays*rays*rays*0.4*vec3(1.0,0.8,0.7);
    307.     col = clamp( col, 0.0, 1.0 );
    308.  
    309.    
    310.     // gamma  
    311.     col = pow( col, vec3(0.45) );
    312.  
    313.     // contrast, desat, tint and vignetting  
    314.     col = col*0.1 + 0.9*col*col*(3.0-2.0*col);
    315.     col = mix( col, vec3(col.x+col.y+col.z)*0.33, 0.2 );
    316.     col *= vec3(1.06,1.05,1.0);
    317.  
    318.     //-------------------------------------
    319.     // velocity vectors (through depth reprojection)
    320.     //-------------------------------------
    321.     float vel = 0.0;
    322.     if( t<0.0 )
    323.     {
    324.         vel = -1.0;
    325.     }
    326.     else
    327.     {
    328.  
    329.         // old camera position
    330.         float oldTime = time - 1.0/30.0; // 1/30 of a second blur
    331.         vec3 oldRo, oldTa; float oldCr, oldFl;
    332.         moveCamera( oldTime, oldRo, oldTa, oldCr, oldFl );
    333.         mat3 oldCam = setCamera( oldRo, oldTa, oldCr );
    334.  
    335.         // world space
    336.         vec3 wpos = ro + rd*t;
    337.         // camera space
    338.         vec3 cpos = vec3( dot( wpos - oldRo, oldCam[0] ),
    339.                           dot( wpos - oldRo, oldCam[1] ),
    340.                           dot( wpos - oldRo, oldCam[2] ) );
    341.         // ndc space
    342.         vec2 npos = oldFl * cpos.xy / cpos.z;
    343.         // screen space
    344.         vec2 spos = 0.5 + 0.5*npos*vec2(iResolution.y/iResolution.x,1.0);
    345.  
    346.  
    347.         // compress velocity vector in a single float
    348.         vec2 uv = fragCoord/iResolution.xy;
    349.         spos = clamp( 0.5 + 0.5*(spos - uv)/0.25, 0.0, 1.0 );
    350.         vel = floor(spos.x*255.0) + floor(spos.y*255.0)*256.0;
    351.     }
    352.    
    353.     fragColor = vec4( col, vel );
    354. }
    , screen:

    upload_2019-2-10_21-21-44.png

    select Gray Noise Medium texture and set Filter "mipmap" and wrap "repeat".
    In Unity, you should try to translate code and you should generate own noise texture, to imitate Gray Noise Medium.

    I remember, I tried to make this kind of texture in Unity, but I had artifacts. But successfully I made this one in C language, for volumetric smoke effect.

    Here is complete C file, and look for SetTexture function:
    Code (CSharp):
    1. // cl smoke.c opengl32.lib user32.lib gdi32.lib
    2. // Przemyslaw Zaworski 11.12.2018
    3.  
    4. #include <windows.h>
    5. #include <GL/gl.h>
    6. #include <math.h>
    7.  
    8. typedef int(__stdcall *PFNWGLSWAPINTERVALEXTPROC)(int i);
    9. typedef GLuint(__stdcall *PFNGLCREATEPROGRAMPROC)();
    10. typedef GLuint(__stdcall *PFNGLCREATESHADERPROC)(GLenum t);
    11. typedef void(__stdcall *PFNGLSHADERSOURCEPROC)(GLuint s, GLsizei c, const char *const *n, const GLint *i);
    12. typedef void(__stdcall *PFNGLCOMPILESHADERPROC)(GLuint s);
    13. typedef void(__stdcall *PFNGLATTACHSHADERPROC)(GLuint p, GLuint s);
    14. typedef void(__stdcall *PFNGLLINKPROGRAMPROC)(GLuint p);
    15. typedef void(__stdcall *PFNGLUSEPROGRAMPROC)(GLuint p);
    16. typedef GLint(__stdcall *PFNGLGETUNIFORMLOCATIONPROC) (GLuint p, const char *n);
    17. typedef void (__stdcall *PFNGLUNIFORM1FVPROC) (GLint k, GLsizei c, const GLfloat *v);
    18. typedef void(__stdcall *PFNGLBINDVERTEXARRAYPROC) (GLuint a);
    19. typedef void(__stdcall *PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint i);
    20. typedef void(__stdcall *PFNGLVERTEXATTRIBPOINTERPROC) (GLuint i, GLint s, GLenum t, GLboolean n, GLsizei k, const void *p);
    21. typedef void(__stdcall *PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint i);
    22. typedef void(__stdcall *PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *a);
    23. typedef void(__stdcall *PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *b);
    24. typedef void(__stdcall *PFNGLBINDBUFFERPROC) (GLenum t, GLuint b);
    25. typedef void(__stdcall *PFNGLBUFFERDATAPROC) (GLenum t, ptrdiff_t s, const GLvoid *d, GLenum u);
    26. typedef void(__stdcall *PFNGLACTIVETEXTUREPROC) (GLenum t);
    27. typedef void(__stdcall *PFNGLUNIFORM1IPROC) (GLint l, GLint v);
    28.  
    29. static const GLfloat vertices[] = {-1.0f,-1.0f,0.0f,1.0f,-1.0f,0.0f,-1.0f,1.0f,0.0f,1.0f,-1.0f,0.0f,1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f};
    30.  
    31. static const char* FragmentShader = \
    32.     "#version 430 \n"
    33.     "layout (location=0) out vec4 color;"
    34.     "uniform float time;"
    35.     "uniform sampler2D hash;"
    36.     "mat3 rotationX(float x)"
    37.     "{"
    38.         "return mat3(1.0,0.0,0.0,0.0,cos(x),sin(x),0.0,-sin(x),cos(x));"
    39.     "}"
    40.     "float noise( in vec3 x )"
    41.     "{"
    42.         "vec3 p = floor(x);"
    43.         "vec3 f = fract(x);"
    44.         "f = f*f*(3.0-2.0*f);"
    45.         "vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;"
    46.         "vec2 rg = textureLod( hash, (uv+ 0.5)/256.0, 0.0 ).yx;"
    47.         "return mix( rg.x, rg.y, f.z );"
    48.     "}"
    49.     "vec4 map( vec3 p )"
    50.     "{"
    51.         "float d = 0.2 - p.y;"  
    52.         "vec3 q = p  - vec3(0.0,1.0,0.0)*time;"
    53.         "float f  = 0.50000*noise( q ); q = q*2.02 - vec3(0.0,1.0,0.0)*time;"
    54.         "f += 0.25000*noise( q ); q = q*2.03 - vec3(0.0,1.0,0.0)*time;"
    55.         "f += 0.12500*noise( q ); q = q*2.01 - vec3(0.0,1.0,0.0)*time;"
    56.         "f += 0.06250*noise( q ); q = q*2.02 - vec3(0.0,1.0,0.0)*time;"
    57.         "f += 0.03125*noise( q );"
    58.         "d = clamp( d + 4.5*f, 0.0, 1.0 );"
    59.         "vec3 col = mix( vec3(1.0,0.9,0.8), vec3(0.4,0.1,0.1), d ) + 0.05*sin(p);"
    60.         "return vec4( col, d );"
    61.     "}"
    62.     "vec3 raymarch( vec3 ro, vec3 rd )"
    63.     "{"
    64.         "vec4 s = vec4( 0,0,0,0 );"
    65.         "float t = 0.0;"  
    66.         "for( int i=0; i<128; i++ )"
    67.         "{"
    68.             "if( s.a > 0.99 ) break;"
    69.             "vec3 p = ro + t*rd;"
    70.             "vec4 k = map( p );"
    71.             "k.rgb *= mix( vec3(3.0,1.5,0.15), vec3(0.5,0.5,0.5), clamp( (p.y-0.2)/2.0, 0.0, 1.0 ) );"
    72.             "k.a *= 0.5;"
    73.             "k.rgb *= k.a;"
    74.             "s = s + k*(1.0-s.a);"  
    75.             "t += 0.05;"
    76.         "}"
    77.         "return clamp( s.xyz, 0.0, 1.0 );"
    78.     "}"
    79.     "void main()"
    80.     "{"
    81.         "vec3 ro = vec3(0.0,4.9,-40.);"
    82.         "vec3 rd = normalize(vec3((2.0*gl_FragCoord.xy-vec2(1280,720))/720,2.0)) * rotationX(5.2);"
    83.         "vec3 volume = raymarch( ro, rd );"
    84.         "volume = volume*0.5 + 0.5*volume*volume*(3.0-2.0*volume);"
    85.         "color = vec4( volume, 1.0 );"
    86.     "}";
    87.  
    88. void SetTexture (int shader, const char *name)
    89. {
    90.     unsigned char Texels [256][256][4];
    91.     for (int i = 0; i < 256; i++)
    92.     {
    93.         for (int j = 0; j < 256; j++)
    94.         {
    95.             float h = (float)fmod(sin(j*12.9898 + i*4.1413)*43758.5453f, 1.0);
    96.             float k = (float)fmod(cos(i*19.6534 + j*7.9813)*51364.8733f, 1.0);
    97.             Texels[j][i][0] = (unsigned char)(h * 255);
    98.             Texels[j][i][2] = (unsigned char)(k * 255);
    99.         }
    100.     }
    101.     for (int i = 0; i < 256; i++)
    102.     {
    103.         for (int j = 0; j < 256; j++)
    104.         {
    105.             int x2 = (j - 17) & 255;
    106.             int y2 = (i - 37) & 255;
    107.             Texels[j][i][1] = Texels[x2][y2][0];
    108.             Texels[j][i][3] = Texels[x2][y2][2];
    109.         }
    110.     }
    111.     ((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(0x84C0);
    112.     glBindTexture(0x806F, 0);
    113.     glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,256,256,0,GL_RGBA,GL_UNSIGNED_BYTE,Texels);
    114.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    115.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    116.     int loc = ((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(shader, name);
    117.     ((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(loc, 0);  
    118. }
    119.  
    120. static LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    121. {
    122.     if( uMsg==WM_SYSCOMMAND && (wParam==SC_SCREENSAVE || wParam==SC_MONITORPOWER) )
    123.         return 0;
    124.     if( uMsg==WM_CLOSE || uMsg==WM_DESTROY || (uMsg==WM_KEYDOWN && wParam==VK_ESCAPE) )
    125.     {
    126.         PostQuitMessage(0);
    127.         return 0;
    128.     }
    129.     if( uMsg==WM_SIZE )
    130.     {
    131.         glViewport( 0, 0, lParam&65535, lParam>>16 );
    132.     }
    133.     if( uMsg==WM_CHAR || uMsg==WM_KEYDOWN)
    134.     {
    135.         if( wParam==VK_ESCAPE )
    136.         {
    137.             PostQuitMessage(0);
    138.             return 0;
    139.         }
    140.     }
    141.     return(DefWindowProc(hWnd,uMsg,wParam,lParam));
    142. }
    143.  
    144. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    145. {
    146.     MSG msg;
    147.     int exit = 0;
    148.     unsigned int VertexBuffer, VertexArrayID;
    149.     PIXELFORMATDESCRIPTOR pfd = { 0,0,PFD_DOUBLEBUFFER };
    150.     WNDCLASS win;
    151.     ZeroMemory( &win, sizeof(WNDCLASS) );
    152.     win.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    153.     win.lpfnWndProc = WindowProc;
    154.     win.hInstance = 0;
    155.     win.lpszClassName = "smoke";
    156.     win.hbrBackground =(HBRUSH)(COLOR_WINDOW+1);
    157.     RegisterClass(&win);
    158.     HDC hdc = GetDC(CreateWindowEx(0, win.lpszClassName, "Volumetric Smoke", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 0, 0, 1280, 720, 0, 0, 0, 0));
    159.     SetPixelFormat(hdc,ChoosePixelFormat(hdc,&pfd),&pfd);
    160.     wglMakeCurrent(hdc,wglCreateContext(hdc));
    161.     ((PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT")) (0);
    162.     ((PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays")) (1, &VertexArrayID);
    163.     ((PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray")) (VertexArrayID);
    164.     ((PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"))(1, &VertexBuffer);
    165.     ((PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"))(0x8892, VertexBuffer);
    166.     ((PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"))(0x8892, sizeof(vertices), vertices, 0x88E4);
    167.     int p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))();
    168.     int s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(0x8B30);
    169.     ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource"))(s, 1, &FragmentShader, 0);
    170.     ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);
    171.     ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"))(p, s);
    172.     ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);
    173.     SetTexture (p, "hash");  
    174.     ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(p);
    175.     GLint location = ((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(p,"time");
    176.     DWORD S = GetTickCount();
    177.     while( !exit )
    178.     {
    179.         while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
    180.         {
    181.             if( msg.message==WM_QUIT ) exit = 1;
    182.             TranslateMessage( &msg );
    183.             DispatchMessage( &msg );
    184.         }
    185.         float t = (GetTickCount()-S)*0.001f;
    186.         ((PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv"))(location, 1, &t);
    187.         ((PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray"))(0);
    188.         ((PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"))(0x8892, VertexBuffer);
    189.         ((PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"))(0,3, GL_FLOAT, GL_FALSE, 0,(void*)0 );
    190.         glDrawArrays(GL_TRIANGLES, 0, 2*3);
    191.         ((PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray"))(0);
    192.         wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE);
    193.     }
    194.     return 0;
    195. }
    upload_2019-2-10_21-30-32.png
     
  16. rottenair

    rottenair

    Joined:
    Apr 29, 2017
    Posts:
    8
    Thank you so much for your help and time. I will do as you have suggested. I will let you know if I run into problems.
     
  17. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328