Unity 6.3
0 онлайн 46 гостей 3 в системе
Вход

Написание вычислительных шейдеров для нескольких платформ

Передовые методы работы с различными платформами

DirectX 11 (DX11) и DirectX 12 (DX12) поддерживают многие действия, которые не поддерживаются на других платформах (таких как Metal или OpenGL ES). Поэтому вы всегда должны убедиться, что ваш шейдер имеет хорошо определенное поведение на платформах, которые предлагают меньшую поддержку, а не только на DX11 или DX12. Вот несколько вещей, которые следует учитывать:

  • DX11 может последовательно возвращать нуль при чтении и читать некоторые записи без проблем, но платформы, которые предлагают меньшую поддержку, могут сбить GPU при этом. Остерегайтесь DX11-специфических хаков, размеров буфера, не соответствующих кратным размера группы потоков, попыток чтения соседних элементов данных из начала или конца буфера и подобных несовместимостей.

  • Инициализируйте ресурсы. Содержимое новых буферов и Текстур не определено. Некоторые платформы могут предоставлять все нули, но на других, может быть что угодно, включая NaNs.

  • Привяжите все ресурсы, которые объявляет ваш вычислительный шейдер. Даже если вы уверены, что из-за ветвления шейдер не использует ресурс в текущем состоянии, вы всё равно должны позаботиться, чтобы ресурс был к нему привязан.

Различия между платформами

  • Metal (для платформ iOS и tvOS) не поддерживает атомарные операции на Текстурах. Metal также не поддерживает запросы GetDimensions на буферы. Передаёт информацию о размере буфера как константу шейдеру, если это необходимо.
  • OpenGL ES 3.1 (для платформ (Android, iOS, tvOS) гарантирует поддержку только 4 вычислительных буферов одновременно. Реальные реализации обычно поддерживают больше, но в целом, если вы разрабатываете для OpenGL ES, вы должны рассмотреть возможность группирования связанных данных в структуры, а не иметь каждый элемент данных в отдельном буфере.
  • OpenGL (ES) и Vulkan требуют квалификатора формата изображения для RWTextures<T>, который не является только для записи.
    Unity получает этот квалификатор от типа T в квадратных скобках. Квалификатор формата должен соответствовать GraphicsFormat/RenderTextureFormat из RenderTexture, который связан с RWTexture. В следующей таблице Unity RenderTexture GraphicsFormats и RenderTextureFormats сопоставлены с их соответствующими квалификаторами типа и формата изображения HLSL:
GraphicsFormat RenderTextureFormat Тип HLSL GLSL квалификационный параметр формата изображения
R32G32B32A32_SFloat ARGBFloat float4 (плавающий) rgba32f
R16G16B16A16_SFloat ARGBHalf min16float4/half4 rgba16f
R32G32_SFloat RGFloat float2 (плавающий) rg32f
R16G16_SFloat RGHalf min16float2/half2 rg16f
B10G11R11_UFloatPack32 RGB111110Float min10float3 r11f_g11f_b10f
R32_SFloat RFloat поплавок r32f
R16_SFloat RHalf min16float/половина r16f
R16G16B16A16_UNorm ARGB64 ненормальный min16float4/half4 rgba16
A2B10G10R10_UNormPack32 ARGB2101010 ненормальный min10float4 rgb10_a2
R8G8B8A8_UNorm ARGB32 ненормальный float4 rgba8
R16G16_UNorm RG32 ненормальный min16float2/half2 rg16
R8G8_UNorm RG16 ненормальный float2 rg8
R16_UNorm R16 ненормальный min16float/половина r16
R8_UNorm R8 ненормированный поплавок r8
R16G16B16A16_SNorm не поддерживается снорм min16float4/half4 rgba16_snorm
R8G8B8A8_SNorm не поддерживается снорм float4 rgba8_snorm
R16G16_SNorm не поддерживается снорм min16float2/half2 rg16_snorm
R8G8_SNorm не поддерживается снорм float2 rg8_snorm
R16_SNorm не поддерживается снорм min16float/половина r16_snorm
R8_SNorm не поддерживается снорм поплавок r8_snorm
R32G32B32A32_SInt ARGBInt int4 rgba32i
R16G16B16A16_SInt не поддерживается min16int4 rgba16i
R8G8B8A8_SInt не поддерживается min12int4 rgba8i
R32G32_SInt RGInt int2 (полное число) rg32i
R16G16_SInt не поддерживается min16int2 rg16i
R8G8_SInt не поддерживается min12int2 rg8i
R32_SInt RInt инт r32i
R16_SInt не поддерживается min16int r16i
R8_SInt не поддерживается min12int r8i
R32G32B32A32_UInt не поддерживается uint4 rgba32i
R16G16B16A16_UInt RGBAUShort min16uint4 rgba16ui
R8G8B8A8_UInt не поддерживается не поддерживается rgba8ui
R32G32_UInt не поддерживается uint2 rg32ui
R16G16_UInt не поддерживается min16uint2 rg16ui
R8G8_UInt не поддерживается не поддерживается rg8ui
R32_UInt не поддерживается УИНТ r32ui
R16_UInt не поддерживается min16uint r16ui
R8_UInt не поддерживается не поддерживается r8ui
A2B10G10R10_UIntPack32 не поддерживается не поддерживается rgb10_a2ui