Объявление
public void DispatchRays(Experimental.Rendering.RayTracingShader rayTracingShader, string rayGenName, uint width, uint height, uint depth, Camera camera);Параметры
rayTracingShader | RayTracingShader для выполнения. |
rayGenName | Имя шейдера генерации лучей. |
width | Ширина сетки потоков шейдера генерации лучей. |
height | Высота сетки потоков шейдера генерации лучей. |
depth | Глубина сетки потоков шейдера генерации лучей. |
camera | Необязательный параметр, используемый для настройки встроенных переменных шейдера, связанных с камерой. |
Описание
Добавляет команду для выполнения RayTracingShader.
При выполнении командного буфера отправляется RayTracingShader, который запускает потоки шейдера генерации лучей, указанного в качестве аргумента. В HLSL значения ширины, высоты и глубины можно получить с помощью функции DispatchRaysDimensions(). Чтобы получить индекс вызова шейдера генерации лучей, можно использовать функцию DispatchRaysIndex() HLSL.
Ширина, высота и глубина должны быть больше нуля и ширина*высота*глубина <= 2^30.
Когда в качестве параметра указана необязательная камера, настраиваются встроенные переменные шейдера, связанные с камерой, экраном и временем. Полный список этих переменных см. в разделе Встроенные переменные шейдера.
#include "UnityShaderVariables.cginc"
#pragma max_recursion_depth 1
// Input
RaytracingAccelerationStructure g_SceneAccelStruct;
float g_Zoom; //Mathf.Tan(Mathf.Deg2Rad * Camera.main.fieldOfView * 0.5f)
// Output
RWTexture2D g_Output;
struct RayPayload
{
float4 color;
};
[shader("miss")]
void MainMissShader(inout RayPayload payload : SV_RayPayload)
{
payload.color = float4(0, 0, 0, 1);
}
[shader("raygeneration")]
void MainRayGenShader()
{
uint2 launchIndex = DispatchRaysIndex().xy;
uint2 launchDim = DispatchRaysDimensions().xy;
float2 frameCoord = float2(launchIndex.x, launchDim.y - launchIndex.y - 1) + float2(0.5, 0.5);
float2 ndcCoords = frameCoord / float2(launchDim.x - 1, launchDim.y - 1);
ndcCoords = ndcCoords * 2 - float2(1, 1);
ndcCoords = ndcCoords * g_Zoom;
float aspectRatio = (float)launchDim.x / (float)launchDim.y;
float3 viewDirection = normalize(float3(ndcCoords.x * aspectRatio, ndcCoords.y, 1));
// Rotate the ray from view space to world space.
float3 rayDirection = normalize(mul((float3x3)unity_CameraToWorld, viewDirection));
RayDesc ray;
ray.Origin = _WorldSpaceCameraPos;
ray.Direction = rayDirection;
ray.TMin = 0.0f;
ray.TMax = 1000.0f;
RayPayload payload;
payload.color = float4(1, 1, 1, 1);
uint missShaderIndex = 0;
TraceRay(g_SceneAccelStruct, 0, 0xFF, 0, 1, missShaderIndex, ray, payload);
g_Output[frameCoord] = payload.color;
}
Это пример простого шейдера генерации лучей, в котором направление луча вычисляется на основе текущего индекса 2D-потока, возвращаемого функцией DispatchRaysIndex(). Вывод будет содержать значение белого цвета, если есть пересечение луча/треугольника, или значение черного цвета, если ничего не произошло (выполняется MainMissShader). В этом примере используется встроенная переменная шейдера unity_CameraToWorld
, и для того, чтобы это значение было установлено правильно, камера должна быть указана в качестве аргумента для функции DispatchRays.