Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Raymarching - metaballs
- //Use as post process shader inside Unity
- Shader "rays/MetaBalls"
- {
- Properties
- {
- [HideInInspector]
- _MainTex ("Texture", 2D) = "white" {}
- [HideInInspector]
- camera("camera",Vector) = (0.0,0.0,0.0,0.0)
- }
- SubShader
- {
- Cull Off ZWrite Off ZTest Always
- Pass
- {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #include "Lighting.cginc"
- // raymarching stuff
- #include "sdfUtilities.cginc"
- uniform sampler2D _CameraDepthTexture;
- uniform sampler2D _MainTex;
- uniform float4x4 _FrustumCornersES;
- uniform float4x4 _CameraInvViewMatrix;
- uniform float4 _MainTex_TexelSize;
- uniform float3 _LightDir;
- uniform float _DrawDistance;
- uniform float4 _Color;
- uniform float _Gloss;
- uniform float _SpecularPower;
- uniform float3 _Center;
- uniform float _Radius;
- struct appdata
- {
- float4 vertex : POSITION;
- float2 uv : TEXCOORD0;
- };
- struct v2f
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- float4 wPos : TEXCOORD2;
- float3 ray : TEXCOORD1;
- };
- #define STEPS 32
- #define MAX_DISTANCE 500
- #define MIN_DISTANCE 0.001
- #define NUM_METABALLS 10
- #define PRECISION 0.01
- #define PI2 6.2831
- v2f vert (appdata v)
- {
- v2f output;
- half index = v.vertex.z;
- v.vertex.z = 0.1;
- output.wPos = mul(unity_ObjectToWorld, v.vertex);
- output.pos = UnityObjectToClipPos(v.vertex);
- output.uv = v.uv;
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- output.uv.y = 1 - output.uv.y;
- #endif
- output.ray = _FrustumCornersES[(int)index].xyz;
- output.ray /= abs(output.ray.z);
- output.ray = mul(_CameraInvViewMatrix, output.ray);
- return output;
- }
- float4 blobs[NUM_METABALLS];
- float SDF_metaBalls(float3 position)
- {
- float m = 0;
- float p = 0;
- float dMin = 0.00001;
- float h = 1.0;
- for (int i =0; i < NUM_METABALLS; i++)
- {
- float db = length(blobs[i].xyz - position);
- if (db < blobs[i].w)
- {
- float x = db/blobs[i].w;
- p += 1.0 - x*x*x*(x*(x*6.0-15.0)+10.0);
- m = 1.0;
- h = max( h, 0.5333*blobs[i].w );
- }
- else
- {
- dMin = min( dMin, db-blobs[i].w);
- }
- }
- float d = dMin + 0.1;
- if (m>0.5)
- {
- float th = 0.2;
- d = h*(th-p);
- }
- return d;
- }
- float map(float3 position)
- {
- return SDF_metaBalls(position);
- }
- float3 norMetaBalls( float3 position)
- {
- float3 norm = float3(0,MIN_DISTANCE, 0);
- for (int i=0; i < NUM_METABALLS; i++)
- {
- float bounding = length (blobs[i].xyz - position);
- float x = saturate(bounding/blobs[i].w);
- float p = 1.0 - x*x*x*(x*(x*6.0-15.0)+10.0);
- norm += normalize( position - blobs[i].xyz ) * p / blobs[i].w;
- }
- return normalize(norm);
- }
- float2 intersection (float3 rayOrigin, float3 rayDirection)
- {
- float h = PRECISION * 2.0;
- float t =0;
- float m = 1.0;
- for (int i = 0; i < MAX_DISTANCE; i++)
- {
- if ( (h < PRECISION) )
- break;
- t += h;
- h = map( rayOrigin+rayDirection *t);
- }
- if (t > MAX_DISTANCE)
- m = -1.0;
- return float2(t,m);
- }
- float SDF_sphere(float3 position, float3 center, float radius )
- {
- return distance(position, center) - radius;
- }
- fixed4 lambert(fixed3 normal, fixed3 viewDirection)
- {
- fixed3 lightDir = _WorldSpaceLightPos0.xyz;
- fixed3 lightCol = _LightColor0.rgb;
- fixed3 halfDir = normalize(lightDir - viewDirection);
- fixed nDotL = saturate ( dot(normal, lightDir));
- fixed specular = pow( dot(normal,halfDir), _SpecularPower )*_Gloss;
- fixed4 finalLight;
- finalLight.rgb = _Color * lightCol * nDotL + specular;
- finalLight.a = 1;
- return finalLight;
- }
- float3 calculateNormals (float3 position)
- {
- return norMetaBalls(position);
- }
- fixed4 renderSurface(float3 position, float3 viewDirection)
- {
- float3 n = calculateNormals(position);
- return lambert(n, viewDirection);
- }
- fixed4 frag (v2f input) : SV_Target
- {
- float3 rayDir = normalize(input.ray.rgb);
- float3 rayOrigin = _WorldSpaceCameraPos;
- //sample framebuffer
- fixed4 color = tex2D( _MainTex, input.uv);
- //get depth
- float zDepth = LinearEyeDepth( tex2D(_CameraDepthTexture, input.uv).r );
- zDepth *= length (input.ray.rgb);
- float time = _Time * 40;
- fixed4 rayCol = 0;
- //movement
- for (int i =0; i < NUM_METABALLS; i++)
- {
- float step = float(i) / STEPS;
- blobs[i].xyz = 2.0 * sin( PI2 * hash3(step*1.17) + hash3(step*13.7)*time );
- blobs[i].w = 1.7+0.9 * sin( PI2* (step*23.1));
- }
- float2 tmat = intersection( rayOrigin, rayDir );
- float4 metaColor = _Color;
- if (tmat.y > -0.5)
- {
- //geo
- float3 pos = rayOrigin + tmat.x*rayDir;
- float3 norm = calculateNormals(pos);
- float3 reflection = reflect(rayDir, norm);
- //mat
- //lit
- float4 lighting = lambert(norm, rayDir);
- //float4 lighting = renderSurface(pos, rayDir);
- metaColor *= lighting;
- color += metaColor;
- }
- rayCol.rgb += metaColor.rgb;
- return rayCol;
- }
- ENDCG
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement