Advertisement
Guest User

Untitled

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