Вычислить шейдерыПрограмма, работающая на графическом процессоре. Подробнее
См. в Словарь программы, которые запускаются на видеокарте вне обычного отрисовкипроцесса рисования графики на экране (или текстуры рендеринга). По умолчанию основная камера в Unity отображает изображение на экране. Подробнее
См. в конвейере Словарь. Их можно использовать для массивно-параллельных алгоритмов GPGPU или для ускорения части рендеринга игр. Для их эффективного использования часто требуется глубокое знание архитектуры графических процессоров и параллельных алгоритмов; а также знание DirectCompute, Вычисления OpenGL, CUDA или OpenCL.
Вычислительные шейдеры в Unity полностью соответствуют технологии DirectX 11 DirectCompute. Платформы, на которых работают вычислительные шейдеры:
Windows и Windows Store с графическим API DirectX 11 или DirectX 12 и графическим процессором Shader Model 5.0
macOS и iOSмобильная операционная система Apple. Подробнее
См. в Словарь, используя Металлическая графика APIПлатформы Android, Linux и Windows с Vulkan API
Современные OpenGL платформы (OpenGL 4.3 в Linux или Windows; OpenGL ES 3.1 в Android). Обратите внимание, что Mac OS X не поддерживает OpenGL 4.3
Современные консоли (Sony PS4 и Microsoft Xbox One)
Поддержку вычислительных шейдеров можно запросить во время выполнения с помощью SystemInfo.supportsComputeShaders.
Вычислительные ресурсы шейдера
Подобно обычным шейдерам, вычислительные шейдеры представляют собой файлы активов в вашем проекте с расширением .compute. Они написаны в стиле DirectX 11 на языке HLSL с минимальное количество директив компиляции #pragma, указывающих, какие функции компилировать как ядра вычислительных шейдеров.
Вот базовый пример файла вычислительного шейдера, который заполняет выходную текстуру красным цветом:
// test.compute
#pragma kernel FillWithRed
RWTexture2D res;
[numthreads(1,1,1)]
void FillWithRed (uint3 dtid : SV_DispatchThreadID)
{
res[dtid.xy] = float4(1,0,0,1);
}
Язык стандартный DX11 HLSL с дополнительной директивой ядра #pragma FillWithRed
. Один файл ресурса вычислительного шейдера должен содержать хотя бы одно вычислительное ядро
, которое может быть вызвано, и эта функция указана в директиве #pragma
. В файле может быть больше ядер; просто добавьте несколько строк #pragma kernel
.
При использовании нескольких строк #pragma kernel
обратите внимание, что комментарии в стиле // text
не допускаются к одному и тому же строку как директивы #pragma kernel
и вызывать ошибки компиляции, если они используются.
За строкой #pragma kernel
может следовать ряд макросов препроцессора, которые необходимо определить при компиляции этого ядра, например:
#pragma kernel KernelOne SOME_DEFINE DEFINE_WITH_VALUE=1337
#pragma kernel KernelTwo OTHER_DEFINE
// ...
Вызов вычислительных шейдеров
В своем скрипте определите переменную типа ComputeShader и назначьте ссылку на актив. Это позволяет вам вызывать их с помощью функции ComputeShader.Dispatch. Дополнительные сведения см. в документации Unity по классу ComputeShader.
С вычислительными шейдерами тесно связан класс ComputeBuffer, определяющий произвольный буфер данных ("структурированный буфер" на жаргоне DX11). Текстуры рендерингаСпециальный тип текстуры, который создается и обновляется во время выполнения. Чтобы использовать их, сначала создайте новую текстуру рендеринга и назначьте одну из ваших камер для рендеринга в нее. Затем вы можете использовать Render Texture в материале, как обычную текстуру. Подробнее
See in Словарь также может быть записан из вычислительных шейдеров, если они имеют “ установлен флаг «произвольный доступ» («представление неупорядоченного доступа» в DX11). Подробнее об этом см. в разделе RenderTexture.enableRandomWrite.
Сэмплеры текстур в вычислительных шейдерах
Текстуры и сэмплеры не являются отдельными объектами в Unity, поэтому для их использования в вычислительных шейдерах необходимо следовать одному из следующих правил Unity:
Используйте то же имя, что и для текстуры, с
sampler
в начале (например,Texture2D MyTex
;SamplerState samplerMyTex
). В этом случае сэмплер инициализируется настройками фильтра/обертки/анизо текстуры этой текстуры.Используйте готовый сэмплер. Для этого имя должно иметь
Linear
илиPoint
(для режима фильтра) иClamp
илиПовторить
(для режима переноса). Например,SamplerState MyLinearClampSampler
создает сэмплер с режимом линейного фильтра и режимом переноса Clamp.
Дополнительную информацию см. в документации по состояниям сэмплера.
Кроссплатформенная поддержка
Как и обычные шейдеры, Unity может преобразовывать вычислительные шейдеры с HLSL на другие языки шейдеров. Поэтому для самых простых кроссплатформенных сборок следует писать вычислительные шейдеры на HLSL. Однако при этом необходимо учитывать некоторые факторы.
Кроссплатформенные рекомендации
DirectX 11 (DX11) поддерживает многие действия, которые не поддерживаются на других платформах (например, Metal или OpenGL ES). Поэтому вы всегда должны следить за тем, чтобы ваш шейдер имел четко определенное поведение на платформах с меньшей поддержкой, а не только на DX11. Вот несколько вещей, которые следует учитывать:
Плохой доступ к памяти за пределами памяти. DX11 может постоянно возвращать ноль при чтении и читать некоторые записи без проблем, но платформы с меньшей поддержкой могут привести к сбою графического процессора при этом. Остерегайтесь взломов, характерных для DX11, размеров буфера, не соответствующих кратному размеру группы потоков, попыток чтения соседних элементов данных из начала или конца буфера и подобных несовместимостей.
Инициализируйте свои ресурсы. Содержимое новых буферов и текстур не определено. Некоторые платформы могут предоставлять только нули, но на других может быть что угодно, включая NaN.
Привяжите все ресурсы, объявленные вашим вычислительным шейдером. Даже если вы точно знаете, что шейдер не использует ресурсы в своем текущем состоянии из-за ветвления, вы все равно должны убедиться, что ресурс привязан к нему.
Различия в зависимости от платформы
Metal (для платформ iOS и tvOS) не поддерживает атомарные операции с текстурами. Metal также не поддерживает запросы
GetDimensions
к буферам. При необходимости передайте шейдеру информацию о размере буфера как константу.OpenGL ES 3.1 (для платформ Android, iOS, tvOS) гарантирует поддержку только 4 вычислительных буферов одновременно. Фактические реализации обычно поддерживают больше, но в целом при разработке для OpenGL ES следует рассмотреть возможность группировки связанных данных в структурах, а не размещения каждого элемента данных в собственном буфере.
Вычислительные шейдеры только для HLSL или только для GLSL
Обычно файлы вычислительных шейдеров записываются на HLSL и компилируются или переводятся на все необходимые платформы автоматически. Однако можно либо запретить перевод на другие языки (то есть оставить только платформы HLSL), либо написать GLSL вычисляет код вручную.
Следующая информация относится только к вычислительным шейдерам только для HLSL или GLSL, а не к кроссплатформенным сборкам. Это связано с тем, что эта информация может привести к тому, что источник вычислительного шейдера будет исключен из некоторых платформ.
Исходный код вычислительного шейдера, окруженный ключевыми словами
CGPROGRAM
иENDCG
, не обрабатывается для платформ, отличных от HLSL. р>Исходный код вычислительного шейдера, окруженный ключевыми словами
GLSLPROGRAM
иENDGLSL
, рассматривается как исходный код GLSL и передается дословно. Это работает только при нацеливании на платформы OpenGL или GLSL. Следует также отметить, что, хотя автоматически переведенные шейдеры соответствуют расположению данных HLSL в буферах, шейдеры GLSL, написанные вручную, следуют правилам размещения данных GLSL.
Варианты и ключевые слова
Вы можете использовать ключевые слова для создания нескольких вариантов вычислительных шейдеров так же, как и для графических шейдеров.
Общую информацию о вариантах см. в разделе Варианты шейдераВерсия программа шейдера, которую Unity генерирует в соответствии с определенной комбинацией ключевых слов шейдера и их статусом. Объект Shader может содержать несколько вариантов шейдера. Подробнее
См. в Словарь. Информацию о том, как реализовать эти функции в вычислительных шейдерах, см. в разделе Объявление и использование ключевых слов шейдера в HLSL и ComputeShader. Документация по API.