yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
c97166aed
master
1implementing fcpw; 2__include ray; 3__include interaction; 4__include bounding_volumes; 5__include transform; 6 7public interface IBranchTraversalWeight 8{ 9 // computes the traversal weight for a given squared distance 10 float compute(float r2); 11}; 12 13public struct ConstantBranchTraversalWeight : IBranchTraversalWeight 14{ 15 // computes the traversal weight for a given squared distance 16 public float compute(float r2) 17 { 18 return 1.0; 19 } 20}; 21 22public interface IAggregate 23{ 24 // updates the bounding volume of an aggregate node 25 [mutating] 26 void refit(uint nodeIndex); 27 28 // intersects aggregate geometry with ray 29 bool intersect(inout Ray r, bool checkForOcclusion, inout Interaction i); 30 31 // intersects aggregate geometry with sphere 32 bool intersect<T : IBranchTraversalWeight>(BoundingSphere s, float3 randNums, 33 T branchTraversalWeight, 34 inout Interaction i); 35 36 // finds closest point on aggregate geometry from sphere center 37 bool findClosestPoint(inout BoundingSphere s, inout Interaction i, 38 bool recordNormal = false); 39 40 // finds closest silhouette point on aggregate geometry from sphere center 41 bool findClosestSilhouettePoint(inout BoundingSphere s, bool flipNormalOrientation, 42 float squaredMinRadius, float precision, 43 inout Interaction i); 44}; 45 46public struct TransformedAggregate<A : IAggregate> : IAggregate 47{ 48 public A aggregate; 49 public float3x4 t; 50 public float3x4 tInv; 51 52 // updates the bounding volume of an aggregate node 53 // NOTE: refitting of transformed aggregates is currently quite inefficient, since the 54 // shared aggregate is refit every time this function is called 55 [mutating] 56 public void refit(uint nodeIndex) 57 { 58 aggregate.refit(nodeIndex); 59 } 60 61 // intersects aggregate geometry with ray 62 public bool intersect(inout Ray r, bool checkForOcclusion, inout Interaction i) 63 { 64 // apply inverse transform to ray 65 Ray rInv = transformRay(tInv, r); 66 67 // intersect 68 bool didIntersect = aggregate.intersect(rInv, checkForOcclusion, i); 69 70 // apply transform to ray and interaction 71 r.tMax = transformRay(t, rInv).tMax; 72 if (didIntersect) 73 { 74 transformInteraction(t, tInv, r.o, true, i); 75 return true; 76 } 77 78 return false; 79 } 80 81 // intersects aggregate geometry with sphere 82 public bool intersect<T : IBranchTraversalWeight>(BoundingSphere s, float3 randNums, 83 T branchTraversalWeight, 84 inout Interaction i) 85 { 86 // apply inverse transform to sphere 87 BoundingSphere sInv = transformSphere(tInv, s); 88 89 // intersect 90 bool didIntersect = aggregate.intersect(sInv, randNums, branchTraversalWeight, i); 91 92 // apply transform to interaction 93 if (didIntersect) 94 { 95 transformInteraction(t, tInv, s.c, false, i); 96 return true; 97 } 98 99 return false; 100 } 101 102 // finds closest point on aggregate geometry from sphere center 103 public bool findClosestPoint(inout BoundingSphere s, inout Interaction i, 104 bool recordNormal = false) 105 { 106 // apply inverse transform to sphere 107 BoundingSphere sInv = transformSphere(tInv, s); 108 109 // find closest point 110 bool didFindClosestPoint = aggregate.findClosestPoint(sInv, i, recordNormal); 111 112 // apply transform to sphere and interaction 113 s.r2 = transformSphere(t, sInv).r2; 114 if (didFindClosestPoint) 115 { 116 transformInteraction(t, tInv, s.c, true, i); 117 return true; 118 } 119 120 return false; 121 } 122 123 // finds closest silhouette point on aggregate geometry from sphere center 124 public bool findClosestSilhouettePoint(inout BoundingSphere s, bool flipNormalOrientation, 125 float squaredMinRadius, float precision, 126 inout Interaction i) 127 { 128 // apply inverse transform to sphere 129 BoundingSphere sInv = transformSphere(tInv, s); 130 BoundingSphere sMin = BoundingSphere(s.c, squaredMinRadius); 131 BoundingSphere sMinInv = transformSphere(tInv, sMin); 132 133 // find closest silhouette point 134 bool didFindClosestSilhouettePoint = aggregate.findClosestSilhouettePoint( 135 sInv, flipNormalOrientation, sMinInv.r2, precision, i); 136 137 // apply transform to sphere and interaction 138 s.r2 = transformSphere(t, sInv).r2; 139 if (didFindClosestSilhouettePoint) 140 { 141 transformInteraction(t, tInv, s.c, true, i); 142 return true; 143 } 144 145 return false; 146 } 147};