Поделиться через


Шейдер пересечения

Шейдер, используемый для реализации пользовательских примитивов пересечения для лучей, пересекающих связанный ограничивающий объем (ограничивающий прямоугольник).

Шейдер пересечения не имеет доступа к полезным данным луча, но определяет атрибуты пересечения для каждого попадания с помощью вызова ReportHit. Обработка ReportHit может остановить шейдер пересечения на раннем этапе, если установлен флаг луча RAY_FLAG_ACCEPT_FIRST_HIT_\AND_\END_SEARCH или метод AcceptHitAndEndSearch вызывается из любого шейдера попадания. В противном случае возвращается значение true, если нажатие было принято, или false, если нажатие было отклонено. Это означает, что любой шейдер нажатия, если он имеется, должен выполниться перед тем, как элемент управления условно вернется в шейдер пересечения.

Атрибут типа шейдера

[shader("intersection")]

Пример

struct CustomPrimitiveDef { ... };
struct MyAttributes { ... };
struct CustomIntersectionIterator {...};
void InitCustomIntersectionIterator(CustomIntersectionIterator it) {...}
bool IntersectCustomPrimitiveFrontToBack(
    CustomPrimitiveDef prim,
    inout CustomIntersectionIterator it,
    float3 origin, float3 dir,
    float rayTMin, inout float curT,
    out MyAttributes attr);

[shader("intersection")]
void intersection_main()
{
    float THit = RayTCurrent();
    MyAttributes attr;
    CustomIntersectionIterator it;
    InitCustomIntersectionIterator(it); 
    while(IntersectCustomPrimitiveFrontToBack(
            CustomPrimitiveDefinitions[LocalConstants.PrimitiveIndex],
            it, ObjectRayOrigin(), ObjectRayDirection(), 
            RayTMin(), THit, attr))
    {
        // Exit on the first hit.  Note that if the ray has
        // RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH or an
        // anyhit shader is used and calls AcceptHitAndEndSearch(),
        // that would also fully exit this intersection shader (making
        // the “break” below moot in that case).        
        if (ReportHit(THit, /*hitKind*/ 0, attr) && (RayFlags() &  RAY_FLAG_FORCE_OPAQUE))
            break;
    }
}