Advertisement
deKaf

[Raymarching] Metaballs

Oct 22nd, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.11 KB | None | 0 0
  1. //Raymarching - metaballs
  2. //Use as post process shader inside Unity
  3.  
  4. Shader "rays/MetaBalls"
  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 float   _Gloss;
  43.             uniform float   _SpecularPower;
  44.  
  45.             uniform float3 _Center;
  46.             uniform float _Radius;
  47.            
  48.  
  49.            
  50.             struct appdata
  51.             {
  52.                 float4 vertex : POSITION;
  53.                 float2 uv : TEXCOORD0;
  54.             };
  55.  
  56.             struct v2f
  57.             {
  58.                 float4 pos : SV_POSITION;
  59.                 float2 uv : TEXCOORD0;
  60.                 float4 wPos : TEXCOORD2;
  61.                 float3 ray : TEXCOORD1;
  62.                
  63.             };
  64.  
  65.             #define STEPS 32
  66.             #define MAX_DISTANCE 500
  67.             #define MIN_DISTANCE 0.001
  68.             #define NUM_METABALLS 10
  69.             #define PRECISION 0.01
  70.             #define PI2 6.2831
  71.            
  72.             v2f vert (appdata v)
  73.             {
  74.                 v2f output;
  75.  
  76.                 half index = v.vertex.z;
  77.                 v.vertex.z = 0.1;
  78.                 output.wPos = mul(unity_ObjectToWorld, v.vertex);
  79.  
  80.                 output.pos = UnityObjectToClipPos(v.vertex);
  81.                 output.uv = v.uv;              
  82.  
  83.                 #if UNITY_UV_STARTS_AT_TOP
  84.                 if (_MainTex_TexelSize.y < 0)
  85.                     output.uv.y = 1 - output.uv.y;
  86.                 #endif
  87.  
  88.                 output.ray = _FrustumCornersES[(int)index].xyz;
  89.                 output.ray /= abs(output.ray.z);
  90.                 output.ray = mul(_CameraInvViewMatrix, output.ray);
  91.                 return output;
  92.             }
  93.  
  94.  
  95.             float4 blobs[NUM_METABALLS];
  96.  
  97.             float SDF_metaBalls(float3 position)
  98.             {
  99.                 float m = 0;
  100.                 float p = 0;
  101.                 float dMin = 0.00001;
  102.                 float h = 1.0;
  103.  
  104.                 for (int i =0; i < NUM_METABALLS; i++)
  105.                 {
  106.                     float db = length(blobs[i].xyz - position);
  107.  
  108.                     if (db < blobs[i].w)
  109.                     {
  110.                         float x = db/blobs[i].w;
  111.                         p += 1.0 - x*x*x*(x*(x*6.0-15.0)+10.0);
  112.                         m = 1.0;
  113.                         h = max( h, 0.5333*blobs[i].w );
  114.                     }
  115.                     else
  116.                     {
  117.                         dMin = min( dMin, db-blobs[i].w);
  118.                     }
  119.                 }
  120.                 float d = dMin + 0.1;
  121.  
  122.                 if (m>0.5)
  123.                 {
  124.                     float th = 0.2;
  125.                     d = h*(th-p);
  126.                 }
  127.                 return d;
  128.             }
  129.             float map(float3 position)
  130.             {
  131.                 return SDF_metaBalls(position);
  132.             }
  133.  
  134.             float3 norMetaBalls( float3 position)
  135.             {
  136.                 float3 norm = float3(0,MIN_DISTANCE, 0);
  137.                 for (int i=0; i < NUM_METABALLS; i++)
  138.                 {
  139.                     float bounding = length (blobs[i].xyz - position);
  140.                     float x = saturate(bounding/blobs[i].w);
  141.                     float p = 1.0 - x*x*x*(x*(x*6.0-15.0)+10.0);
  142.                     norm += normalize( position - blobs[i].xyz ) * p / blobs[i].w;
  143.                 }
  144.             return normalize(norm);
  145.             }
  146.  
  147.             float2 intersection (float3 rayOrigin, float3 rayDirection)
  148.             {
  149.               float h = PRECISION * 2.0;
  150.                 float t =0;
  151.                 float m = 1.0;
  152.                 for (int i = 0; i < MAX_DISTANCE; i++)
  153.                 {
  154.                     if ( (h < PRECISION)  )
  155.                         break;
  156.                    
  157.  
  158.                     t += h;
  159.                     h = map( rayOrigin+rayDirection *t);                    
  160.                 }
  161.                
  162.                 if (t > MAX_DISTANCE)
  163.                     m = -1.0;
  164.  
  165.                 return float2(t,m);
  166.             }
  167.  
  168.            
  169.             float SDF_sphere(float3 position, float3 center, float radius )
  170.             {
  171.                 return distance(position, center) - radius;
  172.                
  173.             }
  174.  
  175.    
  176.             fixed4 lambert(fixed3 normal, fixed3 viewDirection)
  177.             {
  178.                 fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  179.                 fixed3 lightCol = _LightColor0.rgb;
  180.                 fixed3 halfDir = normalize(lightDir - viewDirection);
  181.                 fixed nDotL = saturate ( dot(normal, lightDir));
  182.                 fixed specular = pow( dot(normal,halfDir), _SpecularPower )*_Gloss;
  183.                 fixed4 finalLight;
  184.  
  185.                 finalLight.rgb = _Color * lightCol * nDotL + specular;
  186.                 finalLight.a = 1;
  187.  
  188.                 return finalLight;
  189.             }
  190.            
  191.             float3 calculateNormals (float3 position)
  192.             {
  193.                 return norMetaBalls(position);
  194.             }
  195.  
  196.             fixed4 renderSurface(float3 position, float3 viewDirection)
  197.             {
  198.                 float3 n = calculateNormals(position);
  199.                 return lambert(n, viewDirection);
  200.             }
  201.  
  202.  
  203.  
  204.             fixed4 frag (v2f input) : SV_Target
  205.             {
  206.                 float3 rayDir = normalize(input.ray.rgb);
  207.                 float3 rayOrigin = _WorldSpaceCameraPos;
  208.                
  209.                 //sample framebuffer
  210.                 fixed4 color = tex2D( _MainTex, input.uv);
  211.                 //get depth
  212.                 float zDepth = LinearEyeDepth( tex2D(_CameraDepthTexture, input.uv).r );
  213.                 zDepth *= length (input.ray.rgb);
  214.                
  215.                 float time = _Time * 40;
  216.                 fixed4 rayCol = 0;
  217.  
  218.  
  219.                 //movement
  220.                 for (int i =0; i < NUM_METABALLS; i++)
  221.                 {
  222.                     float step = float(i) / STEPS;
  223.                     blobs[i].xyz = 2.0 * sin( PI2 * hash3(step*1.17) + hash3(step*13.7)*time );
  224.                     blobs[i].w = 1.7+0.9 * sin( PI2* (step*23.1));
  225.                 }
  226.  
  227.                 float2 tmat = intersection( rayOrigin, rayDir );
  228.                 float4 metaColor = _Color;
  229.                
  230.                 if (tmat.y > -0.5)
  231.                 {
  232.                     //geo
  233.                     float3 pos = rayOrigin + tmat.x*rayDir;
  234.                     float3 norm = calculateNormals(pos);
  235.                     float3 reflection = reflect(rayDir, norm);
  236.                     //mat
  237.                    
  238.                     //lit
  239.                     float4 lighting = lambert(norm, rayDir);
  240.                     //float4 lighting = renderSurface(pos, rayDir);
  241.                     metaColor *= lighting;
  242.                     color += metaColor;
  243.                 }
  244.  
  245.  
  246.                 rayCol.rgb += metaColor.rgb;   
  247.                
  248.                 return rayCol;
  249.             }
  250.             ENDCG
  251.         }
  252.     }
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement