Advertisement
JontePonte

double mandelbulb

Dec 26th, 2024
6
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.09 KB | None | 0 0
  1. #pragma kernel CSMain
  2. struct Ray
  3. {
  4. float3 origin;
  5. float3 direction;
  6. };
  7.  
  8. RWTexture2D<float4> Result;
  9. Texture2D<float4> Source;
  10. float maxDst;
  11. float minStepSize;
  12. StructuredBuffer<double> power;
  13. StructuredBuffer<double> spread;
  14. StructuredBuffer<double> scale;
  15. int maxIterations;
  16. float3 lightDir;
  17.  
  18. float4x4 _CameraToWorld;
  19. float4x4 _CameraInverseProjection;
  20.  
  21. double length(double3 f)
  22. {
  23. return sqrt(f.x*f.x + f.y*f.y + f.z*f.z);
  24. }
  25. double dot(double3 f1, double3 f2)
  26. {
  27. return f1.x * f2.x + f1.y * f2.y + f1.z * f2.z;
  28. }
  29.  
  30. // Mandelbulb distance estimation:
  31. // http://blog.hvidtfeldts.net/index.php/2011/09/distance-estimated-3d-fractals-v-the-mandelbulb-different-de-approximations/
  32. double2 DstAndIterations(double3 position) {
  33. position *= scale[0];
  34. double3 z = position * spread[0];
  35. double dr = 1.0;
  36. double r = 0.0;
  37. int iterations = 0;
  38. double powe = power[0];
  39.  
  40. for (int i = 0; i < maxIterations ; i++) {
  41. iterations = i;
  42. r = length(z);
  43.  
  44. if (r>2) {
  45. break;
  46. }
  47.  
  48. // convert to polar coordinates
  49. double theta = acos(z.z/r);
  50. double phi = atan2(z.y,z.x);
  51. dr = pow( r, powe-1.0)*powe*dr + 1.0;
  52.  
  53. // scale and rotate the point
  54. double zr = pow( r,powe) ;
  55. theta = theta*powe;
  56. phi = phi*powe;
  57.  
  58. // convert back to cartesian coordinates
  59. z = zr*float3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
  60. z+=position;
  61. }
  62. double dst = 0.5*log(r)*r/dr;
  63. return float2(iterations,dst*1);
  64. }
  65.  
  66. Ray CreateCameraRay(float2 uv) {
  67. float3 origin = mul(_CameraToWorld, float4(0,0,0,1)).xyz;
  68. float3 direction = mul(_CameraInverseProjection, float4(uv,0,1)).xyz;
  69. direction = mul(_CameraToWorld, float4(direction,0)).xyz;
  70. direction = normalize(direction);
  71.  
  72. Ray ray;
  73. ray.origin = origin;
  74. ray.direction = direction;
  75. return ray;
  76. }
  77.  
  78. float3 CalculateNormal(float3 pos)
  79. {
  80. const float eps = 0.001;
  81.  
  82. float3 f1 = float3(
  83. DstAndIterations(pos + float3(eps, 0.0, 0.0)).y,
  84. DstAndIterations(pos + float3(0.0, eps, 0.0)).y,
  85. DstAndIterations(pos + float3(0.0, 0.0, eps)).y
  86. );
  87. float3 f2 = float3(
  88. DstAndIterations(pos - float3(eps, 0.0, 0.0)).y,
  89. DstAndIterations(pos - float3(0.0, eps, 0.0)).y,
  90. DstAndIterations(pos - float3(0.0, 0.0, eps)).y
  91. );
  92.  
  93. return normalize(f1 - f2);
  94. }
  95.  
  96. [numthreads(8,8,1)]
  97. void CSMain (uint3 id : SV_DispatchThreadID)
  98. {
  99. uint width,height;
  100. Result.GetDimensions(width, height);
  101.  
  102. Result[id.xy] = Source[id.xy];
  103.  
  104. float2 uv = id.xy / float2(width,height) * 2 - 1;
  105. Ray ray = CreateCameraRay(uv);
  106.  
  107. float rayDst = 0;
  108. while(rayDst < maxDst)
  109. {
  110. float2 data = DstAndIterations(ray.origin);
  111.  
  112. ray.origin += ray.direction * data.y;
  113. rayDst += data.y;
  114.  
  115. if(data.y < minStepSize)
  116. {
  117. float3 normal = CalculateNormal(ray.origin);
  118. float brightness = dot(normal, lightDir);
  119. Result[id.xy] = float4(brightness, brightness, brightness, 1);
  120. break;
  121. }
  122. }
  123. }
  124.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement