Стандартный ShaderПрограмма, работающая на графическом процессоре. Подробнее
Посмотреть в Словарь язык в Unity HLSL и общие типы данных HLSL. Однако в Unity есть некоторые дополнения к типам HLSL, особенно для лучшей поддержки на мобильных платформах.
Основные типы данных
Большинство вычислений в шейдерах выполняются над числами с плавающей запятой (в обычных языках программирования, таких как C#, это float
). Присутствует несколько вариантов типов с плавающей запятой: float
, half
и fixed
(а также их векторные/матричные варианты, такие как half3
и float4x4
). Эти типы отличаются точностью (и, следовательно, производительностью или энергопотреблением):
Высокая точность: с плавающей запятой
Значение с плавающей запятой наивысшей точности; обычно 32 бита (так же, как float
из обычных языков программирования).
Полная точность float
обычно используется для позиций в мировом пространстве, текстурных координат или скалярных вычислений, включающих сложные функции, такие как тригонометрия или степень/возведение в степень.
Средняя точность: половина
Значение с плавающей запятой средней точности; обычно 16 бит (диапазон от –60 000 до +60 000 с точностью до 3 десятичных цифр).
Половина точности полезна для коротких векторов, направлений, положений объекта в пространстве, цветов с высоким динамическим диапазоном.
Низкая точность: исправлено
Значение фиксированной точки с наименьшей точностью. Обычно 11 бит, диапазон от –2,0 до +2,0 и точность 1/256.
Фиксированная точность полезна для обычных цветов (которые обычно хранятся в обычных текстурах) и для выполнения простых операций с ними.
Целые типы данных
Целые числа (тип данных int
) часто используются в качестве счетчиков цикла или индексов массива. Для этой цели они обычно отлично работают на разных платформах.
В зависимости от платформы целые типы могут не поддерживаться графическим процессором. Например, графические процессоры Direct3D 9 и OpenGL ES 2.0 работают только с данными с плавающей запятой, а простые на вид целочисленные выражения (включающие битовые или логические операции) могут эмулироваться с помощью довольно сложных математических инструкций с плавающей запятой.
Direct3D 11, OpenGL ES 3, Metal и другие современные платформы должным образом поддерживают целочисленные типы данных, поэтому использование битового сдвига и битовой маскировки работает должным образом.
Составные векторные/матричные типы
HLSL имеет встроенные векторные и матричные типы, созданные из базовых типов. Например, float3
— это трехмерный вектор с компонентами .x, .y, .z, а half4
— это четырехмерный вектор средней точности. вектор с компонентами .x, .y, .z, .w. Кроме того, векторы можно индексировать с помощью компонентов .r, .g, .b, .a, что полезно при работе с цветами.
Матричные типы строятся аналогичным образом; например, float4x4
— это матрица преобразования 4x4. Обратите внимание, что некоторые платформы поддерживают только квадратные матрицы, особенно OpenGL ES 2.0.
Типы текстур/сэмплеров
Обычно вы объявляете текстуры в коде HLSL следующим образом:
sampler2D _MainTex;
samplerCUBE _Cubemap;
Для мобильных платформ это означает "сэмплеры низкой точности", т. е. текстуры должны содержать данные низкой точности. Если вы знаете, что ваша текстура содержит HDRширокий динамический диапазон
Посмотрите в Словарь, вы можете использовать сэмплер половинной точности: р>
sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;
Или, если ваша текстура содержит данные полной точности с плавающей запятой (например, текстура глубины), используйте сэмплер полной точности:
sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;
Точность, поддержка оборудования и производительность
Одна сложность использования типа данных float
/half
/fixed
заключается в том, что графические процессоры ПК всегда обеспечивают высокую точность. То есть для всех графических процессоров ПК (Windows/Mac/Linux) не имеет значения, пишете ли вы float
, half
или фиксированные
типы данных в ваших шейдерах. Они всегда вычисляют все с полной 32-битной точностью с плавающей запятой.
Типы half
и fixed
становятся актуальными только для мобильных графических процессоров, где эти типы в основном существуют для мощности (а иногда и производительность) ограничения. Имейте в виду, что вам нужно протестировать свои шейдеры на мобильных устройствах, чтобы увидеть, сталкиваетесь ли вы с проблемами точности/числа.
Даже на мобильных графических процессорах различная поддержка точности зависит от семейства графических процессоров. Вот обзор того, как каждое семейство мобильных графических процессоров обрабатывает каждый тип с плавающей запятой (обозначается количеством битов, используемых для него):
GPU Family | float | half | fixed |
---|---|---|---|
PowerVR Series 6/7 | 32 | 16 | |
PowerVR SGX 5xx | 32 | 16 | 11 |
Qualcomm Adreno 4xx/3xx | 32 | 16 | |
Qualcomm Adreno 2xx | 32 vertex 24 fragment | ||
ARM Mali T6xx/7xx | 32 | 16 | |
ARM Mali 400/450 | 32 vertex 16 fragment | ||
NVIDIA X1 | 32 | 16 | |
NVIDIA K1 | 32 | ||
NVIDIA Tegra 3/4 | 32 | 16 |
Большинство современных мобильных графических процессоров на самом деле поддерживают либо 32-битные числа (используются для типа float
), либо 16-битные числа (используются как для половина
и фиксированные
типы). Некоторые старые графические процессоры имеют другую точность для вершинного шейдерапрограммы, которая запускается для каждой вершины 3D-модели во время рендеринга модели. Подробнее
См. Словарь и вычисления фрагментного шейдера.
Использование более низкой точности часто может быть быстрее либо из-за улучшенного распределения регистров графического процессора, либо из-за специальных исполнительных блоков «быстрого пути» для определенных математических операций с более низкой точностью. Даже если явного преимущества в производительности нет, использование более низкой точности часто потребляет меньше энергии графического процессора, что приводит к увеличению времени автономной работы.
Общее эмпирическое правило заключается в том, чтобы начинать с половинной точности для всего, кроме положения и координат текстуры. Увеличивайте точность только в том случае, если половинной точности недостаточно для некоторых частей вычислений.
Поддержка бесконечности, NaN и других специальных значений с плавающей запятой
Поддержка специальных значений с плавающей запятой может различаться в зависимости от используемого (в основном мобильного) семейства графических процессоров.
Все графические процессоры ПК, поддерживающие Direct3D 10, поддерживают очень хорошо определенный стандарт IEEE 754 с плавающей запятой. Это означает, что числа с плавающей запятой ведут себя точно так же, как в обычных языках программирования на ЦП.
Мобильные графические процессоры могут иметь несколько разные уровни поддержки. В некоторых случаях деление нуля на ноль может привести к NaN («не число»); в других это может привести к бесконечности, нулю или любому другому неопределенному значению. Обязательно протестируйте свои шейдеры на целевом устройстве, чтобы убедиться, что они поддерживаются.
Внешняя документация по GPU
У поставщиков графических процессоров есть подробные руководства по производительности и возможностям их графических процессоров. Подробнее см. здесь:
- Руководство разработчика по рекомендациям для графических процессоров ARM Mali
- Руководство разработчика Qualcomm Adreno OpenGL ES
- Руководства по архитектуре PowerVR