Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.76 KB | None | 0 0
  1. #pragma kernel CSMain
  2.  
  3. RWTexture2D<float4> Destination;
  4.  
  5. float4x4 _CameraToWorld;
  6. float4x4 _CameraInverseProjection;
  7. float3 _LightDirection;
  8.  
  9. float power;
  10. float darkness;
  11. float blackAndWhite;
  12. float3 colourAMix;
  13. float3 colourBMix;
  14.  
  15. static const float epsilon = 0.001f;
  16. static const float maxDst = 200;
  17. static const int maxStepCount = 250;
  18.  
  19. struct Ray {
  20.     float3 origin;
  21.     float3 direction;
  22. };
  23.  
  24. Ray CreateRay(float3 origin, float3 direction) {
  25.     Ray ray;
  26.     ray.origin = origin;
  27.     ray.direction = direction;
  28.     return ray;
  29. }
  30.  
  31. Ray CreateCameraRay(float2 uv) {
  32.     float3 origin = mul(_CameraToWorld, float4(0, 0, 0, 1)).xyz;
  33.     float3 direction = mul(_CameraInverseProjection, float4(uv, 0, 1)).xyz;
  34.     direction = mul(_CameraToWorld, float4(direction, 0)).xyz;
  35.     direction = normalize(direction);
  36.     return CreateRay(origin, direction);
  37. }
  38.  
  39. float potential(in float3 pos)
  40. {
  41.         float3 z = pos;
  42.         for (int i = 1; i < 15; i++)
  43.         {
  44.             return log(length(z)) / pow(power, float(i));
  45.         }
  46.     return 0.0;
  47. }
  48.  
  49. float2 SceneInfo(float3 p) {
  50.     float pot = potential(p);
  51.     if (pot == 0.0) return 0.0;
  52.     gradient = (float3(potential(p + xDir * EPS), potential(p + yDir * EPS), potential(p + zDir * EPS)) - pot) / EPS;
  53.     return (0.5 / exp(pot))*sinh(pot) / length(gradient);
  54. }
  55.  
  56.  
  57.  
  58. float3 EstimateNormal(float3 p) {
  59.     float x = SceneInfo(float3(p.x + epsilon, p.y, p.z)).y - SceneInfo(float3(p.x - epsilon, p.y, p.z)).y;
  60.     float y = SceneInfo(float3(p.x, p.y + epsilon, p.z)).y - SceneInfo(float3(p.x, p.y - epsilon, p.z)).y;
  61.     float z = SceneInfo(float3(p.x, p.y, p.z + epsilon)).y - SceneInfo(float3(p.x, p.y, p.z - epsilon)).y;
  62.     return normalize(float3(x, y, z));
  63. }
  64.  
  65. [numthreads(8, 8, 1)]
  66. void CSMain(uint3 id : SV_DispatchThreadID)
  67. {
  68.     uint width, height;
  69.     Destination.GetDimensions(width, height);
  70.  
  71.     float2 uv = id.xy / float2(width, height);
  72.  
  73.     // Background gradient
  74.     float4 result = lerp(float4(51, 3, 20, 1), float4(16, 6, 28, 1), uv.y) / 255.0;
  75.  
  76.     // Raymarching:
  77.     Ray ray = CreateCameraRay(uv * 2 - 1);
  78.     float rayDst = 0;
  79.     int marchSteps = 0;
  80.  
  81.     while (rayDst < maxDst && marchSteps < maxStepCount) {
  82.         marchSteps++;
  83.         float2 sceneInfo = SceneInfo(ray.origin);
  84.         float dst = sceneInfo.y;
  85.  
  86.         // Ray has hit a surface
  87.         if (dst <= epsilon) {
  88.             float escapeIterations = sceneInfo.x;
  89.             float3 normal = EstimateNormal(ray.origin - ray.direction*epsilon * 2);
  90.  
  91.             float colourA = saturate(dot(normal*.5 + .5, -_LightDirection));
  92.             float colourB = saturate(escapeIterations / 16.0);
  93.             float3 colourMix = saturate(colourA * colourAMix + colourB * colourBMix);
  94.  
  95.             result = float4(colourMix.xyz, 1);
  96.             break;
  97.         }
  98.         ray.origin += ray.direction * dst;
  99.         rayDst += dst;
  100.     }
  101.  
  102.     float rim = marchSteps / darkness;
  103.     Destination[id.xy] = lerp(result, 1, blackAndWhite) * rim;
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement