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

#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