Advertisement
Zgragselus

Untitled

Aug 17th, 2023
1,116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.79 KB | None | 0 0
  1. // Each #kernel tells which function to compile; you can have many kernels
  2. #pragma kernel Trace
  3.  
  4. struct Triangle
  5. {
  6.     float3 a;
  7.     float3 b;
  8.     float3 c;
  9. };
  10.  
  11. struct BVHNode
  12. {
  13.     float4 l_xy;
  14.     float4 r_xy;
  15.     float4 lr_z;
  16.     uint offset;
  17.     uint primitiveCount;
  18.     uint axis;
  19.     uint pad;
  20. };
  21.  
  22. RWStructuredBuffer<Triangle> _Triangles;
  23. RWStructuredBuffer<BVHNode> _BVHNodes;
  24. RWStructuredBuffer<uint> _BVHIndices;
  25. RWTexture2D<float4> _LightMap;
  26. Texture2D<float4> _RayOrigin;
  27. Texture2D<float4> _RayDirection;
  28. uint _Resolution;
  29. float _Time;
  30.  
  31. #define BVH_STACK_SIZE 64
  32.  
  33. float4 RayTriangleTest(float4 o, float4 d, float3 a, float3 b, float3 c)
  34. {
  35.     float3 e1 = b - a;
  36.     float3 e2 = c - a;
  37.    
  38.     float3 pvec = cross(d.xyz, e2);
  39.     float det = dot(e1, pvec);
  40.    
  41.     if (abs(det) < 0.0001f)
  42.     {
  43.         return float4(0.0f, 0.0f, 0.0f, -1.0f);
  44.     }
  45.    
  46.     float inv_det = 1.0f / det;
  47.    
  48.     float3 tvec = o.xyz - a;
  49.     float bU = dot(tvec, pvec) * inv_det;
  50.     if (bU < 0.0f || bU > 1.0f)
  51.     {
  52.         return float4(0.0f, 0.0f, 0.0f, -1.0f);
  53.     }
  54.    
  55.     float3 qvec = cross(tvec, e1);
  56.     float bV = dot(d.xyz, qvec) * inv_det;
  57.     if (bV < 0.0f || bU + bV > 1.0f)
  58.     {
  59.         return float4(0.0f, 0.0f, 0.0f, -1.0f);
  60.     }
  61.    
  62.     float dist = dot(e2, qvec) * inv_det;
  63.    
  64.     return float4(dist, bU, bV, 1.0f);
  65. }
  66.  
  67. float4 RayAABBTest(float4 o, float4 d, float4 i, float3 bmin, float3 bmax)
  68. {
  69.     float3 v1 = (bmin - o.xyz) * i.xyz;
  70.     float3 v2 = (bmax - o.xyz) * i.xyz;
  71.    
  72.     float3 tnear = min(v1, v2);
  73.     float3 tfar = max(v1, v2);
  74.  
  75.     float tenter = max(tnear.x, max(tnear.y, tnear.z));
  76.     float texit = min(tfar.x, min(tfar.y, tfar.z));
  77.  
  78.     if (tenter < texit && texit > 0.0f)
  79.     {
  80.         return float4(max(tenter, 0.0f), 0.0f, 0.0f, 1.0f);
  81.     }
  82.    
  83.     return float4(0.0f, 0.0f, 0.0f, -1.0f);
  84. }
  85.  
  86. float4 TraceRay(float4 o, float4 d)
  87. {
  88.     /*float tmax = 10000.0f;
  89.     float bU = 0.0f;
  90.     float bV = 0.0f;
  91.    
  92.     int id = -1;
  93.    
  94.     for (uint i = 0; i < 1748; i++)
  95.     {
  96.         float4 tri_res = RayTriangleTest(o, d, _Triangles[i].a, _Triangles[i].b, _Triangles[i].c);
  97.                
  98.         if (tri_res.w > 0.0f)
  99.         {
  100.             if (tri_res.x < tmax && tri_res.x > 0.0f)
  101.             {
  102.                 tmax = tri_res.x;
  103.                 bU = tri_res.y;
  104.                 bV = tri_res.z;
  105.                 id = i;
  106.             }
  107.         }
  108.     }
  109.    
  110.     return float4(bU, bV, tmax, asfloat(id));*/
  111.    
  112.     float4 inv = float4(1.0f / d.x, 1.0f / d.y, 1.0f / d.z, 1.0f);
  113.     float4 oinv = o * inv;
  114.    
  115.     int stack[BVH_STACK_SIZE];
  116.     int stack_ptr = 0;
  117.     stack[stack_ptr] = 0xffffffff;
  118.     uint node_id = 0;
  119.  
  120.     float tmin = 0.0f;
  121.     float tmax = 10000.0f;
  122.     float bU = 0.0f;
  123.     float bV = 0.0f;
  124.     float dist = tmax;
  125.  
  126.     float leaf = 0.0f;
  127.     int id = -1;
  128.    
  129.     float step = 0.0f;
  130.    
  131.     [loop] for (int i = 0; i < 1000; i++)
  132.     {
  133.         step += 1.0f;
  134.        
  135.         // Interior node
  136.         if (_BVHNodes[node_id].primitiveCount == 0)
  137.         {
  138.             // Fetch children bounding boxes
  139.             float4 n0xy = _BVHNodes[node_id].l_xy;
  140.             float4 n1xy = _BVHNodes[node_id].r_xy;
  141.             float4 nz = _BVHNodes[node_id].lr_z;
  142.            
  143.             // Test against child AABBs
  144.             /*float c0lox = n0xy.x * inv.x - oinv.x;
  145.             float c0hix = n0xy.y * inv.x - oinv.x;
  146.             float c0loy = n0xy.z * inv.y - oinv.y;
  147.             float c0hiy = n0xy.w * inv.y - oinv.y;
  148.             float c0loz = nz.x * inv.z - oinv.z;
  149.             float c0hiz = nz.y * inv.z - oinv.z;
  150.             float c1loz = nz.z * inv.z - oinv.z;
  151.             float c1hiz = nz.w * inv.z - oinv.z;
  152.             float c0min = max(max(min(c0lox, c0hix), min(c0loy, c0hiy)), max(min(c0loz, c0hiz), tmin));
  153.             float c0max = min(min(max(c0lox, c0hix), max(c0loy, c0hiy)), min(max(c0loz, c0hiz), tmax));
  154.             float c1lox = n1xy.x * inv.x - oinv.x;
  155.             float c1hix = n1xy.y * inv.x - oinv.x;
  156.             float c1loy = n1xy.z * inv.y - oinv.y;
  157.             float c1hiy = n1xy.w * inv.y - oinv.y;
  158.             float c1min = max(max(min(c1lox, c1hix), min(c1loy, c1hiy)), max(min(c1loz, c1hiz), tmin));
  159.             float c1max = min(min(max(c1lox, c1hix), max(c1loy, c1hiy)), min(max(c1loz, c1hiz), tmax));
  160.            
  161.             bool traverseChild0 = (c0max >= c0min);
  162.             bool traverseChild1 = (c1max >= c1min);*/
  163.            
  164.             float4 c0 = RayAABBTest(o, d, inv, float3(n0xy.x, n0xy.z, nz.x), float3(n0xy.y, n0xy.w, nz.y));
  165.             float4 c1 = RayAABBTest(o, d, inv, float3(n1xy.x, n1xy.z, nz.z), float3(n1xy.y, n1xy.w, nz.w));
  166.            
  167.             bool traverseChild0 = (c0.w >= 0.0f);
  168.             bool traverseChild1 = (c1.w >= 0.0f);
  169.            
  170.             float c0min = c0.x;
  171.             float c1min = c1.x;
  172.            
  173.             // If no children was hit, get node from stack
  174.             if (!traverseChild0 && !traverseChild1)
  175.             {
  176.                 node_id = stack[stack_ptr];
  177.                 stack_ptr--;
  178.             }
  179.             else
  180.             {
  181.                 unsigned int first_child = node_id + 1;
  182.                 unsigned int second_child = _BVHNodes[node_id].offset;
  183.                 node_id = (traverseChild0) ? first_child : second_child;
  184.  
  185.                 if (traverseChild0 && traverseChild1)
  186.                 {
  187.                     if (c1min < c0min)
  188.                     {
  189.                         node_id = second_child;
  190.                         stack_ptr++;
  191.                         stack[stack_ptr] = first_child;
  192.                     }
  193.                     else
  194.                     {
  195.                         stack_ptr++;
  196.                         stack[stack_ptr] = second_child;
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.         else
  202.         {
  203.             int prim_offset = _BVHNodes[node_id].offset;
  204.             for (uint i = 0; i < _BVHNodes[node_id].primitiveCount; i++)
  205.             {
  206.                 int tri_idx = _BVHIndices[prim_offset + i];
  207.                
  208.                 float4 tri_res = RayTriangleTest(o, d, _Triangles[tri_idx].a, _Triangles[tri_idx].b, _Triangles[tri_idx].c);
  209.                
  210.                 if (tri_res.w > 0.0f)
  211.                 {
  212.                     if (tri_res.x < tmax && tri_res.x > 0.0f)
  213.                     {
  214.                         tmax = tri_res.x;
  215.                         bU = tri_res.y;
  216.                         bV = tri_res.z;
  217.                         id = i;
  218.                     }
  219.                 }
  220.             }
  221.            
  222.             node_id = stack[stack_ptr];
  223.             stack_ptr--;
  224.         }
  225.        
  226.         if (node_id == 0xffffffff)
  227.         {
  228.             break;
  229.         }
  230.     }
  231.     //while (node_id != 0xffffffff);
  232.  
  233.     return float4(bU, bV, tmax, asfloat(id));
  234. }
  235.  
  236. [numthreads(8,8,1)]
  237. void Trace(uint3 id : SV_DispatchThreadID)
  238. {
  239.     // Early out on pixels that are outside of texture boundaries
  240.     if (id.x >= _Resolution || id.y >= _Resolution)
  241.     {
  242.         return;
  243.     }
  244.    
  245.     float4 direction = normalize(_RayDirection.Load(id) * 2.0f - 1.0f);
  246.     float4 origin = _RayOrigin.Load(id) + direction * 0.001f;
  247.    
  248.     if (dot(direction, direction) < 0.0002f)
  249.     {
  250.         _LightMap[id.xy] = float4(0.0f, 0.0f, 0.0f, 0.0f);
  251.         return;
  252.     }
  253.    
  254.     float4 res = TraceRay(origin, normalize(float4(-sin(_Time * 6.28f) * 0.05f, 1.0f, cos(_Time * 6.28f) * 0.05f, 1.0f)));
  255.    
  256.     float l = max(dot(direction, normalize(float4(-sin(_Time * 6.28f) * 0.05f, 1.0f, cos(_Time * 6.28f) * 0.05f, 1.0f))), 0.0f);
  257.    
  258.     if (asuint(res.w) != (uint) (-1))
  259.     {
  260.         l *= 0.0f;
  261.     }
  262.    
  263.     //_LightMap[id.xy] = float4(id.x & id.y, (id.x & 15) / 15.0, (id.y & 15) / 15.0, 0.0);
  264.     _LightMap[id.xy] = 0.99f * _LightMap[id.xy] + 0.01f * float4(l, l, l, 1.0f);
  265.  
  266. }
  267.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement