https://raytracing-docs.nvidia.com/optix7/guide/index.html#payload#payload
ray payload는 optixTrace와 ray traverse 중에 호출된 program 간에 데이터를 전달하는 데 사용된다. payload 값은 optixTrace에 전달되고 optixTrace에서 반환되며, copy-in/copy-out semantic을 따른다. payload는 optixTrace 실행 중에 호출되는 모든 intersection, any-hit, closest hit 및 miss program에 전달된다. payload는 32쌍의 optixGetPayload 및 optixSetPayload 함수를 사용하여 각 program에서 읽고 쓸 수 있다. (ex> optixGetPayload_0, optixSetPayload_0) optixSetPayload를 사용하여 payload 값을 설정하면 optixTrace의 호출자에게 반환될 때까지 이후의 모든 optixGetPayload 호출에서 업데이트된 값이 표시된다. program에서 명시적으로 설정되지 않은 payload 값은 수정되지 않은 상태로 유지된다. payload 값은 program 어디세어나 설정할 수 있다. payload는 크기가 제한되어 있으며 최대 32bit 정수 값으로 인코딩되며, 가능한 경우 register에 보관된다. 추가 상태를 유지하기 위해 이러한 값은 stack 기반 변수 또는 Application이 관리하는 전역 메모리에 대한 pointer를 인코딩할 수도 있다.
사용 가능한 payload 값의 수는 OptixPipelineCompileOptions의 numPayloadValues field를 사용하여 전체 pipeline에 대해 전역적으로 구성할 수 있다. pipeline별로 전역으로 구성하면 모든 intersection, any-hit, closest hit 및 miss program이 payload의 값 수에 동일하고, 모든 payload 값에 대한 읽기 및 쓰기 액세스 권한을 갖는다. 따라서 모든 payload 값의 수명은 optixTrace 호출 전체에 걸쳐 확장된다. 따라서 더 큰 payload를 구성하면 일반적으로 레지스터 소비가 증가한다.
또는 사용자가 program별로 더 세분화된 payload 유형을 지정할 수도 있다. 각 payload type은 32bit 정수 값으로 정의되며, 각 값에 대해 특정 읽기/쓰기 semantic이 지정된다. 이러한 semantic이 어떤 program이 특정 payload 값을 읽거나 쓸 수 있는지를 선언한다. optix는 이러한 semantic을 사용하여 payload 값의 수명을 제한하고 레지스터 소비를 개선할 수 있다. 각 optixTrace 호출은 단일 payload 유형과 연관된다. 마찬자기로 각 intersection point, any-hit, closest hit 및 miss program은 하나 이상의 payload 유형과 연관된다. 모듈당 최대 8개의 payload type은 다음과 같이 OptixModuleCompileOptions를 사용하여 지정할 수 있다.
참고 : closest hit 또는 miss shader에 독점적으로 쓰여지고 호출자가 읽는 shader output payload 값은 일반적으로 수명이 가장 짧으므로 (OPTIX_PAYLOAD_SEMANTICS_TRACE_CALLAER_READ | OPTIX_PAYLOAD_SEMANTICS_CH_WRITE | OPTIX_PAYLOAD_SEMANTICS_MS_WRITE) OptiX에 최적화를 가장 많이 제공한다.
OptixPipelineCompileOptions::numPayloadValues를 0으로 설정하면 pipeline의 module의 payload type을 사용한다는 뜻이다. 서로 다른 payload type으로 컴파일된 module은 pipeline에서 자유롭게 결합할 수 있다. module당 최대 payload type은 8개이지만, 서로 다른 payload 유형을 가진 module을 연결할 수 있기 때문에 pipeline 자체는 이 제한을 초과할 수 있다. module 내에서 payload type은 ID로 참조되며, 여기서 유형의 ID는 OptixModuleCompileOptions에 지정된 payload 유형 배열 payloadTypes에 해당 index와 같다. module의 각 program은 optixSetPayloadType 함수를 사용하여 지원되는 payload type을 하나 이상 지정한다. 이 함수가 호출되려면 program code의 최상단에서 무조건 호출되어야 한다. optixSetPayloadTypes에 대한 호출을 생략하거나 OPTIX_PAYLOAD_TYPE_DEFAULT을 인자로 사용하면 program이 optixModuleCompileOptions에 지정된 모든 payload type을 지원함을 나타낸다. optixModuleCompileOptions가 여러 payload type을 지정하는 경우 각 optixTrace 호출은 단일 payload 유형을 제공해야 한다. optixTrace 호출을 실행하는 동안 호출된 모든 program은 해당 optixTrace에 전달된 payload type과 연관되어야 한다. SBT를 설정하면 trace 실행 시 호출되는 모든 program의 payload type이 optixTrace 호출과 연결된 type과 일치하도록 하는 것은 사용자의 책임이다. type의 불일치는 정의되지 않은 동작을 초래한다. 디버그 exception을 활성화하면 program payload type 불일치가 감지되면 OptiX는 OPTIX_EXCEPTION_CODE_PAYLOAD_TYPE_MISMATCH exception을 발생시킨다. optixTrace와 optixSetPayloadType에 전달된 payload type 인자는 컴파일 시간 상수여야 한다. 사용자가 서로 다른 module의 서로 다른 ID에 일치하는 payload type을 할당할 수 있다는 점을 유의해야 한다. payload type은 모듈 내 ID에 관계없이 payload 값의 수와 각 값의 의미가 일치하는 것으로 간주된다.
해당 값에 대한 적절한 읽기 또는 쓰기 semantic 없이 program 내에서 payload 값을 읽거나 쓰면 compile에 실패한다. 여러 type과 연관된 program은 각 유형에 대해 반 번씩 컴파일 된다. program group에 속한 program은 하나의 특정 type에만 연결된다. 사용자는 OptixProgramGroupOptions::payloadType을 사용하여 대상 type을 구성한다. group description에 지정된 모든 program에서 지원되는 고유한 payload type이 하나만 있는 경우 OptiX는 고유한 type을 추론하고 OptixProgramGroupOptions::payloadType은 0으로 남을 수 있다.