ドキュメント

Unity Engine


User Manual

Script Reference

Unity Engine


Writing compute shaders for multiple platforms

Best practices for writing compute shaders that work on multiple platforms.
読み終わるまでの所要時間 3 分最終更新 13日前

Cross-platform best practices

DirectX 11 (DX11) and DirectX 12 (DX12) support many actions that are not supported on other platforms (such as Metal or OpenGL ES). Therefore, you should always ensure your shader has well-defined behavior on platforms that offer less support, rather than only on DX11 or DX12. Here are few things to consider:
  • Out-of-bounds memory accesses are bad. DX11 might consistently return zero when reading, and read some writes without issues, but platforms that offer less support might crash the GPU when doing this. Watch out for DX11-specific hacks, buffer sizes not matching with multiple of your thread group size, trying to read neighboring data elements from the beginning or end of the buffer, and similar incompatibilities.
  • Initialize your resources. The contents of new buffers and Textures are undefined. Some platforms might provide all zeroes, but on others, there could be anything including NaNs.
  • Bind all the resources your compute shader declares. Even if you know for sure that the shader does not use resources in its current state because of branching, you must still ensure a resource is bound to it.

Platform-specific differences

  • Metal (for iOS and tvOS platforms) does not support atomic operations on Textures. Metal also does not support
    GetDimensions
    queries on buffers. Pass the buffer size info as constant to the shader if needed.
  • OpenGL ES 3.1 (for (Android, iOS, tvOS platforms) only guarantees support for 4 compute buffers at a time. Actual implementations typically support more, but in general if developing for OpenGL ES, you should consider grouping related data in structs rather than having each data item in its own buffer.
  • OpenGL (ES) and Vulkan require an image format qualifier for
    RWTextures<T>
    that are not write-only.
    Unity derives this qualifier from the type T in the angle-brackets. The format qualifier needs to match the GraphicsFormat/RenderTextureFormat of the RenderTexture that is bound to the RWTexture. The following table maps Unity RenderTexture GraphicsFormats and RenderTextureFormats to their corresponding HLSL type and image format qualifier:

GraphicsFormat

RenderTextureFormat

HLSL type

GLSL image format qualifier

R32G32B32A32_SFloatARGBFloatfloat4rgba32f
R16G16B16A16_SFloatARGBHalfmin16float4/half4rgba16f
R32G32_SFloatRGFloatfloat2rg32f
R16G16_SFloatRGHalfmin16float2/half2rg16f
B10G11R11_UFloatPack32RGB111110Floatmin10float3r11f_g11f_b10f
R32_SFloatRFloatfloatr32f
R16_SFloatRHalfmin16float/halfr16f
R16G16B16A16_UNormARGB64unorm min16float4/half4rgba16
A2B10G10R10_UNormPack32ARGB2101010unorm min10float4rgb10_a2
R8G8B8A8_UNormARGB32unorm float4rgba8
R16G16_UNormRG32unorm min16float2/half2rg16
R8G8_UNormRG16unorm float2rg8
R16_UNormR16unorm min16float/halfr16
R8_UNormR8unorm floatr8
R16G16B16A16_SNormunsupportedsnorm min16float4/half4rgba16_snorm
R8G8B8A8_SNormunsupportedsnorm float4rgba8_snorm
R16G16_SNormunsupportedsnorm min16float2/half2rg16_snorm
R8G8_SNormunsupportedsnorm float2rg8_snorm
R16_SNormunsupportedsnorm min16float/halfr16_snorm
R8_SNormunsupportedsnorm floatr8_snorm
R32G32B32A32_SIntARGBIntint4rgba32i
R16G16B16A16_SIntunsupportedmin16int4rgba16i
R8G8B8A8_SIntunsupportedmin12int4rgba8i
R32G32_SIntRGIntint2rg32i
R16G16_SIntunsupportedmin16int2rg16i
R8G8_SIntunsupportedmin12int2rg8i
R32_SIntRIntintr32i
R16_SIntunsupportedmin16intr16i
R8_SIntunsupportedmin12intr8i
R32G32B32A32_UIntunsupporteduint4rgba32i
R16G16B16A16_UIntRGBAUShortmin16uint4rgba16ui
R8G8B8A8_UIntunsupportedunsupportedrgba8ui
R32G32_UIntunsupporteduint2rg32ui
R16G16_UIntunsupportedmin16uint2rg16ui
R8G8_UIntunsupportedunsupportedrg8ui
R32_UIntunsupporteduintr32ui
R16_UIntunsupportedmin16uintr16ui
R8_UIntunsupportedunsupportedr8ui
A2B10G10R10_UIntPack32unsupportedunsupportedrgb10_a2ui