Cg (сокращение от C for Graphics ) и High-Level Shader Language (HLSL) — это два названия высокоуровневого языка шейдеров, разработанного Nvidia и Microsoft для программирования шейдеров . Cg/HLSL основан на языке программирования C , и хотя они используют один и тот же синтаксис, некоторые функции C были изменены и добавлены новые типы данных, чтобы сделать Cg/HLSL более подходящим для программирования графических процессоров . [1] [2]
Существуют две основные ветви языка Cg/HLSL: компилятор Nvidia Cg (cgc), который выводит DirectX или OpenGL , и Microsoft HLSL, который выводит шейдеры DirectX в формате байт-кода. [3] [4] Cgc от Nvidia был объявлен устаревшим в 2012 году, без какой-либо дополнительной разработки или поддержки. [5]
Шейдеры HLSL могут включать множество спецэффектов как в 2D, так и в 3D компьютерной графике . Первоначально язык Cg/HLSL включал поддержку только вершинных шейдеров и пиксельных шейдеров , но постепенно были введены и другие типы шейдеров:
Из-за технических достижений в области графического оборудования некоторые области программирования 3D-графики стали довольно сложными. Чтобы упростить процесс, в видеокарты были добавлены новые функции, включая возможность изменять конвейеры рендеринга с помощью вершинных и пиксельных шейдеров.
В начале вершинные и пиксельные шейдеры программировались на очень низком уровне только с помощью языка ассемблера графического процессора. Хотя использование языка ассемблера давало программисту полный контроль над кодом и гибкость, его было довольно сложно использовать. Нужен был переносимый язык более высокого уровня для программирования GPU, поэтому был создан Cg, чтобы преодолеть эти проблемы и упростить разработку шейдеров.
Некоторые преимущества использования Cg по сравнению с ассемблированием:
Cg имеет шесть основных типов данных. Некоторые из них такие же, как в C, а другие специально добавлены для программирования GPU. Вот эти типы:
Cg также имеет векторные и матричные типы данных, основанные на базовых типах данных, таких как float3 и float4x4. Такие типы данных довольно распространены при работе с программированием 3D-графики. Cg также имеет типы данных struct и array , которые работают аналогично своим эквивалентам в C.
Cg поддерживает широкий спектр операторов, включая общие арифметические операторы из C, эквивалентные арифметические операторы для векторных и матричных типов данных, а также общие логические операторы .
Cg разделяет основные структуры управления с C, такие как if/else, while и for. Он также имеет похожий способ определения функций.
Cg реализует множество директив препроцессора C и его систему макрорасширений. Он реализует #include
. [7]
Программы Cg создаются для различных профилей шейдеров , которые соответствуют графическим процессорам с различными возможностями. [8] Эти профили определяют, среди прочего, сколько инструкций может быть в каждом шейдере, сколько регистров доступно и какие ресурсы может использовать шейдер. Даже если программа корректна, она может быть слишком сложной для работы с профилем. [7]
По мере увеличения количества профилей и типов шейдеров Microsoft перешла на использование термина «Шейдерная модель» для группировки набора профилей, обнаруженных в поколении графических процессоров. [9] Cg поддерживает некоторые из новых профилей вплоть до Shader Model 5.0, а также трансляцию в glsl или hlsl. [8]
«32 + 64» для исполняемых инструкций означает «32 текстурные инструкции и 64 арифметические инструкции».
Как и в C, Cg/HLSL предлагает набор функций для общих задач в программировании GPU. Некоторые функции имеют эквиваленты в C, например, математические функции abs и sin, в то время как другие специализируются на задачах программирования GPU, например, функции отображения текстур tex1D и tex2D.
Программы Cg — это просто вершинные и пиксельные шейдеры, и им нужны вспомогательные программы, которые обрабатывают остальную часть процесса рендеринга. Cg можно использовать с двумя графическими API : OpenGL или DirectX . У каждого есть свой набор функций Cg для взаимодействия с программой Cg, например, установка текущего шейдера Cg, передача параметров и т. д.
Помимо возможности компилировать исходный код Cg в ассемблерный код, среда выполнения Cg также может компилировать шейдеры во время выполнения поддерживающей программы. Это позволяет среде выполнения компилировать шейдер с использованием последних оптимизаций, доступных для оборудования, на котором в данный момент выполняется программа. Однако эта техника требует, чтобы исходный код шейдера был доступен компилятору в виде простого текста, что позволяет пользователю программы получить доступ к исходному коду шейдера. Некоторые разработчики считают это серьезным недостатком этой техники.
Чтобы избежать раскрытия исходного кода шейдера и при этом сохранить некоторые оптимизации, специфичные для оборудования, была разработана концепция профилей. Шейдеры могут быть скомпилированы для различных платформ графического оборудования (в соответствии с профилями). При выполнении поддерживающей программы загружается лучший/наиболее оптимизированный шейдер в соответствии с его профилем. Например, может быть профиль для видеокарты, которая поддерживает сложные пиксельные шейдеры, и другой профиль для той, которая поддерживает только минимальные пиксельные шейдеры. Создавая пиксельный шейдер для каждого из этих профилей, поддерживающая программа увеличивает количество поддерживаемых аппаратных платформ, не жертвуя качеством изображения на мощных системах.
У диалекта Cg всегда был только один компилятор — инструментарий Cg от Nvidia.
Microsoft выпустила два компилятора для HLSL. Первоначальным компилятором был закрытый исходный код FXC (Effect Compiler), поддерживаемый до 2015 года. Он был устарел в пользу открытого исходного кода DXC (DirectXShaderCompiler) на основе LLVM с поддержкой новых функций HLSL. [21] Оба компилятора генерируют байт-код: в то время как старый FXC использовал DXBC, DXC теперь использует DXIL. DXC также может генерировать байт-код SPIR-V . [22]
Группа Khronos также написала компилятор HLSL на основе LLVM в виде интерфейса для glslang , их компилятора GLSL-to-SPIR_V. Поддержка SPIR-V означает, что шейдеры могут быть кроссплатформенными, больше не ограничивая их стеком DirectX. [23] Ранее эта задача выполнялась конвертерами на уровне исходного кода, такими как HLSL2GLSL , но полученный код часто оказывается раздутым. [24]
Язык шейдеров PlayStation (PSSL) основан на Cg/HLSL. [25]
Язык шейдинга ReshadeFX также основан на Cg/HLSL. Шейдеры, написанные на ReshadeFX, компилируются в OpenGL, DX или Vulkan и внедряются в игры для работы в качестве фильтров постобработки. [26]