Created
April 1, 2020 07:05
-
-
Save ALEXMORF/218443f22c8e52e2ffcb09f7e642cb96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ray_result RayTraceBottomLevel(float3 Ro, float3 Rd, float3 InvRd, | |
bool StopOnAnyHit, | |
ray_result RayState, uint Stack[STACK_SIZE], | |
int StackIndex, | |
RWStructuredBuffer<bvh_node> BLASBuffer, | |
RWStructuredBuffer<prim> PrimBuffer, | |
int InstanceIndex, | |
int NodeOffset, int PrimOffset) | |
{ | |
int StackBase = StackIndex; | |
int Cursor = StackBase; | |
Stack[++Cursor] = 0; | |
while (Cursor > StackBase) | |
{ | |
uint NodeIndex = Stack[Cursor--]; | |
bvh_node Node = BLASBuffer[NodeOffset+NodeIndex]; | |
uint PrimCount = GetPrimCount(Node.Data); | |
float BoxT = RayIntersectBox(Ro, InvRd, Node.Min, Node.Max); | |
if (BoxT < RayState.ClosestT) | |
{ | |
if (PrimCount == 0) // internal node | |
{ | |
uint Axis = GetAxis(Node.Data); | |
if (Rd[Axis] > 0.0) | |
{ | |
Stack[++Cursor] = Node.Offset; | |
Stack[++Cursor] = NodeIndex + 1; | |
} | |
else | |
{ | |
Stack[++Cursor] = NodeIndex + 1; | |
Stack[++Cursor] = Node.Offset; | |
} | |
} | |
else // instance leaf | |
{ | |
for (int PrimI = 0; PrimI < PrimCount; ++PrimI) | |
{ | |
prim P = PrimBuffer[PrimOffset+Node.Offset+PrimI]; | |
float3 Res = RayIntersectTri(Ro, Rd, | |
P.Verts[0], | |
P.Verts[1], | |
P.Verts[2]); | |
float T = Res.x; | |
if (T > 0.0 && T < RayState.ClosestT) | |
{ | |
RayState.ClosestT = T; | |
RayState.InstanceIndex = InstanceIndex; | |
RayState.PrimID = P.ID; | |
RayState.UV = Res.yz; | |
if (StopOnAnyHit) | |
{ | |
return RayState; | |
} | |
} | |
} | |
} | |
} | |
} | |
return RayState; | |
} | |
ray_result RayTraceTwoLevel(float3 Ro, float3 Rd, float3 InvRd, | |
float Extent, | |
bool StopOnAnyHit, | |
StructuredBuffer<bvh_node> TLASBuffer, | |
StructuredBuffer<instance> InstanceBuffer, | |
RWStructuredBuffer<bvh_node> BLASBuffer, | |
RWStructuredBuffer<prim> PrimBuffer) | |
{ | |
ray_result RayState = InitRayResult(); | |
RayState.ClosestT = Extent; | |
uint Stack[STACK_SIZE]; | |
int Cursor = -1; | |
Stack[++Cursor] = 0; | |
while (Cursor >= 0 && Cursor < STACK_SIZE) | |
{ | |
uint NodeIndex = Stack[Cursor--]; | |
bvh_node Node = TLASBuffer[NodeIndex]; | |
uint PrimCount = GetPrimCount(Node.Data); | |
float BoxT = RayIntersectBox(Ro, InvRd, Node.Min, Node.Max); | |
if (BoxT < RayState.ClosestT) | |
{ | |
if (PrimCount == 0) // internal node | |
{ | |
uint Axis = GetAxis(Node.Data); | |
if (Rd[Axis] > 0.0) | |
{ | |
Stack[++Cursor] = Node.Offset; | |
Stack[++Cursor] = NodeIndex + 1; | |
} | |
else | |
{ | |
Stack[++Cursor] = NodeIndex + 1; | |
Stack[++Cursor] = Node.Offset; | |
} | |
} | |
else // instance leaf | |
{ | |
int InstanceIndex = Node.Offset; | |
instance Instance = InstanceBuffer[InstanceIndex]; | |
float3 InstanceRo = mul(float4(Ro, 1.0), Instance.InvT.Data).xyz; | |
float3 InstanceRd = mul(float4(Rd, 0.0), Instance.InvT.Data).xyz; | |
float3 InstanceInvRd = rcp(InstanceRd); | |
RayState = RayTraceBottomLevel(InstanceRo, InstanceRd, | |
InstanceInvRd, | |
StopOnAnyHit, | |
RayState, | |
Stack, Cursor, | |
BLASBuffer, PrimBuffer, | |
InstanceIndex, | |
Instance.NodeOffset, | |
Instance.PrimOffset); | |
if (StopOnAnyHit && RayState.ClosestT < Extent) | |
{ | |
return RayState; | |
} | |
} | |
} | |
} | |
return RayState; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment