Advertisement
deKaf

[Raymarching]Terrain

Oct 22nd, 2019
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.80 KB | None | 0 0
  1. // Terrain via raymarching
  2. // Use in Unity as Post Process shader
  3.  
  4. Shader "rays/Terrain"
  5. {
  6.     Properties
  7.     {
  8.        
  9.         [HideInInspector]
  10.         _MainTex ("Texture", 2D) = "white" {}
  11.         [HideInInspector]
  12.         camera("camera",Vector) = (0.0,0.0,0.0,0.0)
  13.     }
  14.     SubShader
  15.     {
  16.        
  17.         Cull Off ZWrite Off ZTest Always
  18.         Pass
  19.         {
  20.             CGPROGRAM
  21.             #pragma vertex vert
  22.             #pragma fragment frag
  23.            
  24.            
  25.             #include "UnityCG.cginc"
  26.             #include "Lighting.cginc"
  27.             // raymarching stuff
  28.             #include "sdfUtilities.cginc"
  29.  
  30.  
  31.             uniform sampler2D _CameraDepthTexture;
  32.             uniform sampler2D _MainTex;
  33.            
  34.             uniform float4x4 _FrustumCornersES;
  35.             uniform float4x4 _CameraInvViewMatrix;
  36.             uniform float4 _MainTex_TexelSize;
  37.    
  38.             uniform float3 _LightDir;
  39.             uniform float _DrawDistance;
  40.            
  41.             uniform float4   _Color;
  42.             uniform float4  _FogColor;
  43.             uniform float   _Gloss;
  44.             uniform float   _SpecularPower;
  45.  
  46.             uniform float3 _Center;
  47.             uniform float _Radius;
  48.            
  49.  
  50.            
  51.             struct appdata
  52.             {
  53.                 float4 vertex : POSITION;
  54.                 float2 uv : TEXCOORD0;
  55.             };
  56.  
  57.             struct v2f
  58.             {
  59.                 float4 pos : SV_POSITION;
  60.                 float2 uv : TEXCOORD0;
  61.                 float4 wPos : TEXCOORD2;
  62.                 float3 ray : TEXCOORD1;
  63.                
  64.             };
  65.  
  66.             #define STEPS 1024
  67.             #define MAX_DISTANCE 500
  68.             #define MIN_DISTANCE 0.001
  69.            
  70.             #define PRECISION 0.001
  71.             #define PI 3.14159265359
  72.             #define PI2 6.2831
  73.             #define FOG_EXTINCTION 0.2
  74.            
  75.             v2f vert (appdata v)
  76.             {
  77.                 v2f output;
  78.  
  79.                 half index = v.vertex.z;
  80.                 v.vertex.z = 0.1;
  81.                 output.wPos = mul(unity_ObjectToWorld, v.vertex);
  82.  
  83.                 output.pos = UnityObjectToClipPos(v.vertex);
  84.                 output.uv = v.uv;              
  85.  
  86.                 #if UNITY_UV_STARTS_AT_TOP
  87.                 if (_MainTex_TexelSize.y < 0)
  88.                     output.uv.y = 1 - output.uv.y;
  89.                 #endif
  90.  
  91.                 output.ray = _FrustumCornersES[(int)index].xyz;
  92.                 output.ray /= abs(output.ray.z);
  93.                 output.ray = mul(_CameraInvViewMatrix, output.ray);
  94.                 return output;
  95.             }
  96.  
  97.  
  98.    
  99.             fixed4 lambert(fixed3 normal, fixed3 viewDirection)
  100.             {
  101.                 fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  102.                 fixed3 lightCol = _LightColor0.rgb;
  103.                 fixed3 halfDir = normalize(lightDir - viewDirection);
  104.                 fixed nDotL = saturate ( dot(normal, lightDir));
  105.                 fixed specular = pow( dot(normal,halfDir), _SpecularPower )*_Gloss;
  106.                 fixed4 finalLight;
  107.  
  108.                 finalLight.rgb = _Color * lightCol * nDotL + specular;
  109.                 finalLight.a = 1;
  110.  
  111.                 return finalLight;
  112.             }
  113.  
  114.             float noise (float3 n)
  115.             {
  116.                 return frac(sin(dot(n, float3(95.43583, 93.323197, 94.993431))) * 65536.32);
  117.             }
  118.  
  119.             float perlin_a (float3 n)
  120.             {
  121.                 float3 base = floor(n * 64.0) * 0.015625;
  122.                 float3 dd = float3(0.015625, 0.0, 0.0);
  123.                 float a = noise(base);
  124.                 float b = noise(base + dd.xyy);
  125.                 float c = noise(base + dd.yxy);
  126.                 float d = noise(base + dd.xxy);
  127.                 float3 p = (n - base) * 64.0;
  128.                 float t = lerp(a, b, p.x);
  129.                 float tt = lerp(c, d, p.x);
  130.                 return lerp(t, tt, p.y);
  131.             }
  132.  
  133.             float perlin_b (float3 normal)
  134.             {
  135.                 float3 base = float3(normal.x, normal.y, floor(normal.z * 64.0) * 0.015625);
  136.                 float3 dd = float3(0.015625, 0.0, 0.0);
  137.                 float3 p = (normal - base) *  64.0;
  138.                 float front = perlin_a(base + dd.yyy);
  139.                 float back = perlin_a(base + dd.yyx);
  140.                 return lerp(front, back, p.z);
  141.             }
  142.  
  143.             float fbm(float3 normal)
  144.             {
  145.                 float total = 0.0;
  146.                 float m1 = 1.0;
  147.                 float m2 = 0.1;
  148.                 for (int i = 0; i < 5; i++)
  149.                 {
  150.                     total += perlin_b(normal * m1) * m2;
  151.                     m2 *= 2.0;
  152.                     m1 *= 0.5;
  153.                 }
  154.                 return total;
  155.             }
  156.  
  157.             float3 heightMap (float3 normal)
  158.             {
  159.                 return float3(fbm((5.0 * normal) + fbm((5.0 * normal) * 3.0 - 1000.0) * 0.05),0,0);
  160.             }
  161.  
  162.             float map(float3 position)
  163.             {
  164.  
  165.                 return position.y-32.0*float4(float3( (heightMap(float3(position.xz*0.005,1.0)*0.1)-1.0)),1.0).r;
  166.             }
  167.            
  168.             float3 calculateNormals (float3 position)
  169.             {
  170.                 const float eps = 0.01;
  171.                 return normalize (float3( map(position+ float3(eps, 0, 0) )
  172.                                          - map(position- float3(eps, 0, 0) ),  
  173.  
  174.                                          map(position+ float3(0, eps, 0) )
  175.                                           - map (position- float3(0, eps, 0) ),
  176.  
  177.                                         map(position+ float3(0, 0, eps) )
  178.                                          - map(position- float3(0, 0, eps) )
  179.                                          )
  180.                                          );
  181.  
  182.             }
  183.  
  184.             fixed4 renderSurface(float3 position, float3 viewDirection)
  185.             {
  186.                 float3 n = calculateNormals(position);
  187.                 return lambert(n, viewDirection);
  188.             }
  189.  
  190.             float SDFplane( float3 position, float4 normal)
  191.             {
  192.                 normal = normalize(normal);
  193.                 return dot(position, normal.rgb) + normal.w;
  194.             }
  195.  
  196.             float getHeight(float x, float z)
  197.             {
  198.                 return sin(x)*sin(z);
  199.             }
  200.  
  201.             bool castRay( float3 rayOrigin, float3 rayDirection, float resT)
  202.             {
  203.                 float delt = MIN_DISTANCE;
  204.                 float minT = MAX_DISTANCE;
  205.                 float maxT = STEPS;
  206.  
  207.                 for (float t = minT; t < maxT; t+=delt)
  208.                 {
  209.                     float3 position = rayOrigin + rayDirection *t;
  210.                    
  211.                     if ( position.y < getHeight(position.x, position.z) )
  212.                     {
  213.                         resT = t - 0.5f * delt;
  214.                         return true;
  215.                     }
  216.                 }
  217.  
  218.             return false;
  219.             }
  220.             float3 applyFog( float3 shading, float distance)
  221.             {
  222.                 float fog = 1.0 - exp(distance * FOG_EXTINCTION);
  223.                 float4 fogColor = _FogColor;
  224.                 return lerp(shading, fogColor.rgb, fog);  
  225.             }
  226.  
  227.             float4 terrainColor(float3 rayOrigin, float3 rayDirection, float t)
  228.             {
  229.                 float3 position = rayOrigin + rayDirection * t;
  230.                 float3 normals = calculateNormals(position);
  231.                 float3 shading = renderSurface(position, normals );
  232.  
  233.                 return float4(applyFog(shading, t), 1);
  234.             }
  235.  
  236.             float4 rayMarch (float3 rayOrigin, float3 rayDirection)
  237.             {
  238.                 for (int i=0; i< STEPS; i++)
  239.                 {
  240.                     float t = map(rayOrigin);
  241.                    
  242.                     //for perf - break when max_distance is reached
  243.                     if (rayOrigin.x> MAX_DISTANCE || rayOrigin.x< -MAX_DISTANCE || rayOrigin.z> MAX_DISTANCE || rayOrigin.z< -MAX_DISTANCE) break; // size
  244.  
  245.                     if ( t< PRECISION )
  246.                        
  247.                         return float4( applyFog ( float3( 5.0/rayOrigin.y,0.0,0.0 ), t) , 1);
  248.                        
  249.                     rayOrigin+=t*rayDirection;
  250.                 }
  251.                 return 0;
  252.             }
  253.  
  254.             fixed4 frag (v2f input) : SV_Target
  255.             {
  256.                 float3 rayDir = normalize(input.ray.rgb);
  257.                 float3 rayOrigin = _WorldSpaceCameraPos;
  258.                 float3 worldPos = input.wPos;
  259.                 float3 viewDirection = normalize(input.wPos - rayOrigin);
  260.                 //sample framebuffer
  261.                 fixed4 color = tex2D( _MainTex, input.uv);
  262.  
  263.                 //get depth
  264.                 float zDepth = LinearEyeDepth( tex2D(_CameraDepthTexture, input.uv).r );
  265.                 zDepth *= length (input.ray.rgb);
  266.                
  267.                 float4 rayCastTerrain = rayMarch(rayOrigin,rayDir);
  268.                 return lerp(color, rayCastTerrain , rayCastTerrain.a);
  269.                
  270.             }
  271.             ENDCG
  272.         }
  273.     }
  274. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement