You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
5.9 KiB
226 lines
5.9 KiB
#ifndef _UNIFIEDRAYTRACING_TRACERAY_HLSL_
|
|
#define _UNIFIEDRAYTRACING_TRACERAY_HLSL_
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl"
|
|
#if defined(UNIFIED_RT_BACKEND_COMPUTE)
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl"
|
|
#endif
|
|
|
|
namespace UnifiedRT
|
|
{
|
|
|
|
#ifndef UNIFIED_RT_PAYLOAD
|
|
#pragma message("Error, you must define UNIFIED_RT_PAYLOAD before including TraceRay.hlsl")
|
|
#endif
|
|
|
|
#if defined(UNIFIED_RT_BACKEND_HARDWARE)
|
|
|
|
float3 _WorldRayOrigin() { return WorldRayOrigin(); }
|
|
float3 _WorldRayDirection() { return WorldRayDirection(); }
|
|
float _RayTMin() { return RayTMin(); }
|
|
float _RayTCurrent() { return RayTCurrent(); }
|
|
uint _InstanceID() { return InstanceID(); }
|
|
uint _InstanceIndex() { return InstanceIndex(); }
|
|
uint _PrimitiveIndex() { return PrimitiveIndex(); }
|
|
|
|
struct HitContext
|
|
{
|
|
float2 barycentrics;
|
|
|
|
float3 WorldRayOrigin()
|
|
{
|
|
return _WorldRayOrigin();
|
|
}
|
|
|
|
float3 WorldRayDirection()
|
|
{
|
|
return _WorldRayDirection();
|
|
}
|
|
|
|
float RayTMin()
|
|
{
|
|
return _RayTMin();
|
|
}
|
|
|
|
float RayTCurrent()
|
|
{
|
|
return _RayTCurrent();
|
|
}
|
|
|
|
uint InstanceIndex()
|
|
{
|
|
return _InstanceIndex();
|
|
}
|
|
|
|
uint InstanceID()
|
|
{
|
|
return _InstanceID();
|
|
}
|
|
|
|
uint PrimitiveIndex()
|
|
{
|
|
return _PrimitiveIndex();
|
|
}
|
|
|
|
float2 UvBarycentrics()
|
|
{
|
|
return barycentrics;
|
|
}
|
|
|
|
bool IsFrontFace()
|
|
{
|
|
return (HitKind() == HIT_KIND_TRIANGLE_FRONT_FACE);
|
|
}
|
|
};
|
|
|
|
void TraceRay(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags, inout UNIFIED_RT_PAYLOAD payload)
|
|
{
|
|
RayDesc rayDesc;
|
|
rayDesc.Origin = ray.origin;
|
|
rayDesc.TMin = ray.tMin;
|
|
rayDesc.Direction = ray.direction;
|
|
rayDesc.TMax = ray.tMax;
|
|
|
|
TraceRay(accelStruct.accelStruct, rayFlags, instanceMask, 0, 1, 0, rayDesc, payload);
|
|
}
|
|
|
|
#elif defined(UNIFIED_RT_BACKEND_COMPUTE)
|
|
|
|
struct HitContext
|
|
{
|
|
float3 worldRayOrigin;
|
|
float3 worldRayDirection;
|
|
float tmin;
|
|
float tcurrent;
|
|
uint instanceID;
|
|
uint primitiveIndex;
|
|
float2 barycentrics;
|
|
bool isFrontFace;
|
|
|
|
float3 WorldRayOrigin()
|
|
{
|
|
return worldRayOrigin;
|
|
}
|
|
|
|
float3 WorldRayDirection()
|
|
{
|
|
return worldRayDirection;
|
|
}
|
|
|
|
float RayTMin()
|
|
{
|
|
return tmin;
|
|
}
|
|
|
|
float RayTCurrent()
|
|
{
|
|
return tcurrent;
|
|
}
|
|
|
|
uint InstanceID()
|
|
{
|
|
return instanceID;
|
|
}
|
|
|
|
uint PrimitiveIndex()
|
|
{
|
|
return primitiveIndex;
|
|
}
|
|
|
|
float2 UvBarycentrics()
|
|
{
|
|
return barycentrics;
|
|
}
|
|
|
|
bool IsFrontFace()
|
|
{
|
|
return isFrontFace;
|
|
}
|
|
};
|
|
|
|
} // namespace UnifiedRT
|
|
|
|
#ifdef UNIFIED_RT_ANYHIT_FUNC
|
|
uint UNIFIED_RT_ANYHIT_FUNC(UnifiedRT::HitContext hitContext, inout UNIFIED_RT_PAYLOAD payload);
|
|
#endif
|
|
|
|
#ifdef UNIFIED_RT_CLOSESTHIT_FUNC
|
|
void UNIFIED_RT_CLOSESTHIT_FUNC(UnifiedRT::HitContext hitContext, inout UNIFIED_RT_PAYLOAD payload);
|
|
#endif
|
|
|
|
namespace UnifiedRT {
|
|
|
|
#pragma warning(disable : 3557) // prevent warning when the "while (rayQuery.Proceed())" loop is unrolled
|
|
|
|
void TraceRay(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags, inout UNIFIED_RT_PAYLOAD payload)
|
|
{
|
|
#ifdef UNIFIED_RT_ANYHIT_FUNC
|
|
RayQuery rayQuery;
|
|
rayQuery.Init(dispatchInfo.globalThreadIndex, dispatchInfo.localThreadIndex, accelStruct, rayFlags, instanceMask, ray);
|
|
while (rayQuery.Proceed())
|
|
{
|
|
// not necessary but makes sure the compiler optimizes the loop out when one of these flags is set
|
|
if (rayFlags & (UnifiedRT::kRayFlagForceOpaque | UnifiedRT::kRayFlagCullNonOpaque))
|
|
break;
|
|
|
|
HitContext hitContext;
|
|
hitContext.worldRayOrigin = rayQuery.WorldRayOrigin();
|
|
hitContext.worldRayDirection = rayQuery.WorldRayDirection();
|
|
hitContext.tmin = rayQuery.RayTMin();
|
|
hitContext.tcurrent = rayQuery.CandidateTriangleRayT();
|
|
hitContext.instanceID = rayQuery.CandidateInstanceID();
|
|
hitContext.primitiveIndex = rayQuery.CandidatePrimitiveIndex();
|
|
hitContext.barycentrics = rayQuery.CandidateTriangleBarycentrics();
|
|
hitContext.isFrontFace = rayQuery.CandidateTriangleFrontFace();
|
|
|
|
uint res = UNIFIED_RT_ANYHIT_FUNC(hitContext, payload);
|
|
|
|
if (res != UnifiedRT::kIgnoreHit)
|
|
rayQuery.CommitNonOpaqueTriangleHit();
|
|
|
|
if (res == UnifiedRT::kAcceptHitAndEndSearch)
|
|
rayQuery.Abort();
|
|
|
|
}
|
|
#else
|
|
RayQuery rayQuery;
|
|
rayQuery.Init(dispatchInfo.globalThreadIndex, dispatchInfo.localThreadIndex, accelStruct, rayFlags | UnifiedRT::kRayFlagForceOpaque, instanceMask, ray);
|
|
rayQuery.Proceed();
|
|
#endif
|
|
|
|
#ifdef UNIFIED_RT_CLOSESTHIT_FUNC
|
|
if (!(rayFlags & kRayFlagSkipClosestHit) && rayQuery.CommittedStatus() == kCommittedTriangleHit)
|
|
{
|
|
HitContext hitContext;
|
|
hitContext.worldRayOrigin = rayQuery.WorldRayOrigin();
|
|
hitContext.worldRayDirection = rayQuery.WorldRayDirection();
|
|
hitContext.tmin = rayQuery.RayTMin();
|
|
hitContext.tcurrent = rayQuery.CommittedRayT();
|
|
hitContext.instanceID = rayQuery.CommittedInstanceID();
|
|
hitContext.primitiveIndex = rayQuery.CommittedPrimitiveIndex();
|
|
hitContext.barycentrics = rayQuery.CommittedTriangleBarycentrics();
|
|
hitContext.isFrontFace = rayQuery.CommittedTriangleFrontFace();
|
|
|
|
UNIFIED_RT_CLOSESTHIT_FUNC(hitContext, payload);
|
|
}
|
|
#endif
|
|
|
|
#ifdef UNIFIED_RT_MISS_FUNC
|
|
if (rayQuery.CommittedStatus() == kCommittedNothing)
|
|
{
|
|
HitContext hitContext = (HitContext)0;
|
|
hitContext.worldRayOrigin = rayQuery.WorldRayOrigin();
|
|
hitContext.worldRayDirection = rayQuery.WorldRayDirection();
|
|
hitContext.tmin = rayQuery.RayTMin();
|
|
|
|
UNIFIED_RT_MISS_FUNC(hitContext, payload);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} // namespace UnifiedRT
|
|
|
|
#endif // UNIFIEDRAYTRACING_TRACERAY_HLSL
|