yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Yong HeFix type checking on generic extensions. (#5316)c97166aed

master
4.8 KiB147 linesraw
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};