Advertisement
Guest User

Untitled

a guest
Oct 13th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Custom/RaycastSphere"
  2. {
  3.     Properties
  4.     {
  5.         _Radius ("Radius", float) = 0.3
  6.         _Centre ("Centre", vector) = (1,1,1) // See distanceEstimate()
  7.         _Steps ("Steps", int) = 64 // higher values cause some ugly noise. Not sure how to fix that.
  8.     }
  9.     SubShader
  10.     {
  11.         Tags { "Queue"="Transparent" "RenderType"="Transparent"}
  12.         LOD 100
  13.  
  14.         ZWrite Off
  15.         ZTest Always
  16.         Cull Off
  17.         Blend SrcAlpha OneMinusSrcAlpha
  18.  
  19.         Pass
  20.         {
  21.             CGPROGRAM
  22.             #pragma vertex vert
  23.             #pragma fragment frag
  24.  
  25.             #include "UnityCG.cginc"
  26.  
  27.             float3 _Centre;
  28.             float _Radius;
  29.             int _Steps;
  30.  
  31.             struct appdata
  32.             {
  33.                 float4 vertex : POSITION;
  34.             };
  35.  
  36.             struct v2f
  37.             {
  38.                 float4 vertex : SV_POSITION;
  39.                 float3 wPos : TEXCOORD1;
  40.             };
  41.  
  42.             //Called for each vertex on the surface of the object
  43.             //Normally this is where you'd get the UV's and apply textures, but we don't care about that
  44.             v2f vert (appdata v)
  45.             {
  46.                 v2f o;
  47.                 o.vertex = UnityObjectToClipPos(v.vertex);
  48.                 o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  49.                 // ^ The location of the point in world coordinates
  50.                 return o;
  51.             }
  52.  
  53.             bool sphereHit (float3 position) // Returns whether or not a ray has entered the geometry
  54.             {
  55.                 return distance(fmod(abs(position), 2), _Centre) < (_Radius+0.000001);
  56.                 // Extra 0.00...1 is to avoid floating point errors. You get some interesting effects if you take it out
  57.             }
  58.  
  59.             float distanceEstimate(float3 position) // Calculates the distance to the geometry given a point in space
  60.             {
  61.                 return distance(fmod(abs(position), 2), _Centre) - _Radius;
  62.                 // Notice the mod 2 here. Effectively the world space is confined to the range 0-2. If you go past 2, you
  63.                 // wind up back at 0. You'll want to keep the center of the sphere between 0-2 as a result.
  64.             }
  65.  
  66.             // march our ray forward until it hits something, or we pass _Steps
  67.             int raycastHit (float3 position, float3 direction)
  68.             {
  69.                 for (int i = 0; i < _Steps; i++)
  70.                 {
  71.                     if ( sphereHit(position) )
  72.                     {
  73.                         return i;
  74.                     }
  75.                     position += direction * distanceEstimate(position);
  76.                 }
  77.                 return -1; // no collision
  78.             }
  79.  
  80.             //Fragments are visible bits of surface
  81.             //Each one of these is tested in parallel for contact with our interior geometry
  82.             fixed4 frag (v2f i) : SV_Target
  83.             {
  84.                 float3 viewDirection = normalize(i.wPos - _WorldSpaceCameraPos);
  85.                 // ^ the unit vector connecting our camera to the point our ray intersects the surface of our object
  86.                 int steps_taken = raycastHit(_WorldSpaceCameraPos, viewDirection);
  87.                 // ^ how many steps it takes to reach our geometry. -1 If no collision
  88.                 if (steps_taken > 0)
  89.                 {
  90.                     return fixed4(1-(0.02*steps_taken),0,0,1); // More steps -> darker shade of red
  91.                     // a better solution would be a proper brightness transform using matricies
  92.                 }
  93.                 else
  94.                 {
  95.                     return fixed4(0,0,0,0); //Transparent if no collision
  96.                 }
  97.             }
  98.             ENDCG
  99.         }
  100.     }
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement