Справочные материалы по переносу с GLSL на HLSL
Вы переносите код с GLSL на HLSL, когда портируете графическую архитектуру с OpenGL ES 2.0 на Direct3D 11, чтобы создавать игры для универсальной платформы Windows (UWP). Язык GLSL, о котором пойдет речь в этом разделе, совместим с OpenGL ES 2.0. Язык HLSL совместим с Direct3D 11. Подробнее об отличиях Direct3D 11 от предыдущих версий Direct3D см. в разделе Сопоставление компонентов.
- Сравнение OpenGL ES 2.0 и Direct3D 11
- Перенос переменных GLSL в HLSL
- Перенос типов GLSL в HLSL
- Перенос предварительно определенных глобальных переменных GLSL в HLSL
- Пример переноса переменных GLSL в HLSL
- Примеры переноса кода отрисовки OpenGL в Direct3D
- Связанные темы
Сравнение OpenGL ES 2.0 и Direct3D 11
Между OpenGL ES 2.0 и Direct3D 11 много общего. У них похожие конвейеры отрисовки и графические компоненты. Но Direct3D 11 представляет собой реализацию отрисовки и API, а не спецификацию. OpenGL ES 2.0 является спецификацией отрисовки и API, а не реализацией. В целом Direct3D 11 и OpenGL ES 2.0 отличаются в следующем.
OpenGL ES 2.0 | Direct3D 11 |
---|---|
Не зависящая от оборудования и операционной системы спецификация с реализациями, предоставленными поставщиком | Реализация аппаратной абстракции Майкрософт и сертификация на платформах Windows |
Отделенная для поддержки многообразия оборудования среда выполнения управляет большей частью ресурсов | Прямой доступ к аппаратной структуре; приложение может управлять ресурсами и обработкой |
Предоставляет модули более высокого уровня через сторонние библиотеки (например, SDL) | Модули более высокого уровня, такие как Direct2D, основаны на модулях более низкого уровня, чтобы упростить разработку приложений для Windows |
Поставщики оборудования различаются с помощью расширений | Майкрософт добавляет к API универсальные дополнительные компоненты, чтобы они не были специфическими ни для одного конкретного поставщика |
GLSL и HLSL отличаются в следующем.
GLSL | HLSL |
---|---|
Процессуальный, сконцентрированный на этапах (как C) | Объектно-ориентированный, сконцентрированный на данных (как C++) |
Компиляция шейдера интегрирована в графический API | Компилятор HLSL компилирует шейдер в промежуточное двоичное представление, прежде чем Direct3D передает его драйверу.
Примечание Это двоичное представление не зависит от оборудования. Оно обычно компилируется во время сборки приложения, а не во время его выполнения.
|
Модификаторы хранилищ переменных | Буферы констант и передачи данных через объявления входных макетов |
Стандартный тип вектора: vec2/3/4 lowp, mediump, highp |
Стандартный тип вектора: float2/3/4 min10float, min16float |
texture2D [функция] | texture.Sample [тип_данных.функция] |
sampler2D [тип_данных] | Texture2D [тип_данных] |
Развернутые по строкам матрицы (по умолчанию) | Развернутые по столбцам матрицы (по умолчанию)
Примечание Используйте модификатор типа row_major , чтобы изменить макет для одной переменной. Подробнее см. Синтаксис переменной. Вы также можете указать флажок компилятора или псевдокомментарий, чтобы изменить глобальное значение по умолчанию.
|
Шейдер фрагмента | Построитель текстуры |
Примечание HLSL содержит текстуры и образцы как два отдельных объекта. В GLSL, как в Direct3D 9, привязка текстуры является частью состояния дискретизатора.
В GLSL вы представляете значительную часть состояния OpenGL в виде предопределенных глобальных переменных. Например, в GLSL используется переменная gl_Position для указания положения вершины и переменная gl_FragColor для указания цвета фрагмента. В HLSL вы явно передаете состояние Direct3D из кода приложения в шейдер. Например, при использовании Direct3D и HLSL данные, введенные в вершинный шейдер, должны соответствовать формату данных в буфере вершины, а структура буфера констант в коде приложения должна соответствовать структуре буфера констант (cbuffer) в коде шейдера.
Перенос переменных GLSL в HLSL
В GLSL вы применяете модификаторы (квалификаторы) к объявлению глобальной переменной шейдера, чтобы обеспечить определенные реакции этой переменной на события в вашем шейдере. В HLSL вам не нужны эти модификаторы, потому что вы определяете поток шейдера с помощью аргументов, которые передаете шейдеру и возвращаете от него.
Поведение переменной GLSL | Эквивалент HLSL |
---|---|
Однородный элемент Вы передаете неизменную переменную из кода приложения в вершинный шейдер и (или) шейдер фрагмента. Вы должны передать значения всех неизменных переменных перед отрисовкой какого-либо треугольника с помощью этих шейдеров, чтобы их значения остались теми же во время отрисовки треугольной сетки. Эти значения не меняются. Некоторые неизменные значения устанавливаются для всего кадра, другие — для одной конкретной пары вершина-пиксель. Неизменные переменные индивидуальны для полигона. |
Используйте буфер констант. См. разделы Краткое руководство: создание буфера констант и Постоянные шейдера. |
Различной Вы инициализируете меняющуюся переменную в вершинном шейдере и передаете ее меняющейся переменной с таким же названием в шейдере фрагмента. Так как вершинный шейдер устанавливает только значение меняющейся переменной для каждой вершины, средство прорисовки интерполирует эти значения (надлежащим с точки зрения перспективы образом), чтобы генерировать значения для каждого фрагмента и передать их в шейдер фрагмента. Эти переменные меняются от треугольника к треугольнику. |
Используйте структуру, которую возвращаете от вершинного шейдера, в качестве входных данных для построителя текстуры. Убедитесь, что семантические значения совпадают. |
атрибут Атрибут является частью описания вершины, которое вы передаете из кода приложения только в вершинный шейдер. В отличие от неизменного значения вы устанавливаете значение каждого атрибута для каждой вершины, что, в свою очередь, позволяет всем вершинам иметь разные значения. Переменные атрибутов индивидуальны для вершин. |
Определите буфер вершины в коде приложения Direct3D и обеспечьте его соответствие входным данным вершины, определенным в вершинном шейдере. При желании определите буфер индексов. См. разделы Краткое руководство: создание буфера вершины и Краткое руководство: создание буфера индексов. Создайте макет входных данных в коде приложения Direct3D и обеспечьте соответствие семантических значений семантическим значениям входных данных вершины. См. раздел Создание входного макета. |
const Постоянные, которые компилируются в шейдер и никогда не меняются. |
Используйте static const static означает, что значение не предоставляется буферам констант, const означает, что шейдер не может изменить значение. Таким образом, значение известно во время компиляции на основании инициализатора. |
В GLSL переменные без модификаторов являются лишь простыми глобальными переменными, частными для каждого шейдера.
Когда вы передаете данные текстурам (Texture2D в HLSL) и их соответствующим дискретизаторам (SamplerState в HLSL), вы обычно объявляете их как глобальные переменные в построителе текстуры.
Перенос типов GLSL в HLSL
Используйте эту таблицу для переноса типов GLSL в HLSL.
Тип GLSL | Тип HLSL |
---|---|
скалярные типы: float, int, bool | скалярные типы: float, int, bool также uint, double Подробнее: Скалярные типы. |
векторные типы
|
векторные типы
Подробнее см. в разделах Тип вектора и Ключевые слова. тип вектора также можно определить, как float4 (typedef vector <float, 4> vector;). Дополнительные сведения см. в разделе Определяемый пользователем тип. |
тип матрицы
|
тип матрицы
Вы также можете воспользоваться типом матрицы, чтобы определить матрицу. Например: matrix <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f}; тип матрицы также можно определить как float4x4 (typedef matrix <float, 4, 4> matrix;). Дополнительные сведения см. в разделе Определяемый пользователем тип. |
Квалификатор точности для числа с плавающей запятой, целого числа, дискретизатора
|
типы точности
Подробнее см. в разделах Скалярные типы и Использование минимальной точности HLSL. |
sampler2D | Texture2D |
samplerCube | TextureCube |
Перенос предварительно определенных глобальных переменных GLSL в HLSL
Используйте эту таблицу для переноса предварительно определенных глобальных переменных GLSL в HLSL.
Предварительно определенные глобальные переменные GLSL | Семантика HLSL |
---|---|
gl_Position Эта переменная относится к типу vec4. Положение вершины например, - gl_Position = position; |
SV_Position POSITION в Direct3D 9 Эта семантика относится к типу float4. Выходные данные вершинного шейдера Положение вершины например, - float4 vPosition : SV_Position; |
gl_PointSize Эта переменная относится к типу float. Размер точки |
PSIZE Значение отсутствует, если вы не используете Direct3D 9 Эта семантика относится к типу float. Выходные данные вершинного шейдера Размер точки |
gl_FragColor Эта переменная относится к типу vec4. Цвет фрагмента например, - gl_FragColor = vec4(colorVarying, 1.0); |
SV_Target COLOR в Direct3D 9 Эта семантика относится к типу float4. Выходные данные построителя текстуры Цвет пикселя например, - float4 Color[4] : SV_Target; |
gl_FragData[n] Эта переменная относится к типу vec4. Цвет фрагмента для прикрепления цвета n |
SV_Target[n] Эта семантика относится к типу float4. Выходное значение построителя текстуры, которое хранится в однобуферной прорисовке n, где 0 <= n <= 7. |
gl_FragCoord Эта переменная относится к типу vec4. Положение фрагмента в буфере кадров |
SV_Position Отсутствует в Direct3D 9 Эта семантика относится к типу float4. Входные данные построителя текстуры Координаты пространства экрана например, - float4 screenSpace : SV_Position |
gl_FrontFacing Эта переменная относится к типу bool. Определяет, принадлежит ли фрагмент лицевому примитиву. |
SV_IsFrontFace VFACE в Direct3D 9 SV_IsFrontFace относится к типу bool. VFACE относится к типу float. Входные данные построителя текстуры Лицевая поверхность примитива |
gl_PointCoord Эта переменная относится к типу vec2. Положение фрагмента в пределах точки (только растеризация точки) |
SV_Position VPOS в Direct3D 9 SV_Position относится к типу float4. VPOS относится к типу float2. Входные данные построителя текстуры Положение пикселя или образца на пространстве экрана например, - float4 pos : SV_Position |
gl_FragDepth Эта переменная относится к типу float. Данные буфера глубины |
SV_Depth DEPTH в Direct3D 9 SV_Depth относится к типу float. Выходные данные построителя текстуры Данные буфера глубины |
Вы используете семантику, чтобы указать положение, цвет и прочие сведения для входных данных вершинного шейдера и построителя текстуры. Значения семантики в макете входных данных должны соответствовать входным данным вершинного шейдера. Например, см. раздел Примеры переноса переменных GLSL в HLSL. Подробнее о семантике HLSL: Семантика.
Пример переноса переменных GLSL в HLSL
Здесь мы приведем примеры использования переменных GLSL в коде OpenGL/GLSL и эквивалентный пример в коде Direct3D/HLSL.
Неизменная переменная, атрибут и меняющаяся переменная в GLSL
Код приложения OpenGL
// Uniform values can be set in app code and then processed in the shader code.
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
// Incoming position of vertex
attribute vec4 position;
// Incoming color for the vertex
attribute vec3 color;
// The varying variable tells the shader pipeline to pass it
// on to the fragment shader.
varying vec3 colorVarying;
Код вершинного шейдера GLSL
//The shader entry point is the main method.
void main()
{
colorVarying = color; //Use the varying variable to pass the color to the fragment shader
gl_Position = position; //Copy the position to the gl_Position pre-defined global variable
}
Код шейдера фрагмента GLSL
void main()
{
//Pad the colorVarying vec3 with a 1.0 for alpha to create a vec4 color
//and assign that color to the gl_FragColor pre-defined global variable
//This color then becomes the fragment's color.
gl_FragColor = vec4(colorVarying, 1.0);
}
Буферы констант и передача данных в HLSL
Вот пример передачи данных вершинному шейдеру HLSL, которые затем направляются построителю текстуры. В коде приложения определите вершину и буфер констант. Затем в коде вершинного шейдера определите буфер констант как cbuffer и сохраните индивидуальные данные вершины и входные данные построителя текстуры. Здесь мы используем структуры, называемые VertexShaderInput и PixelShaderInput.
Код приложения Direct3D
struct ConstantBuffer
{
XMFLOAT4X4 model;
XMFLOAT4X4 view;
XMFLOAT4X4 projection;
};
struct SimpleCubeVertex
{
XMFLOAT3 pos; // position
XMFLOAT3 color; // color
};
// Create an input layout that matches the layout defined in the vertex shader code.
const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
// Create vertex and index buffers that define a geometry.
Код вершинного шейдера HLSL
cbuffer ModelViewProjectionCB : register( b0 )
{
matrix model;
matrix view;
matrix projection;
};
// The POSITION and COLOR semantics must match the semantics in the input layout Direct3D app code.
struct VertexShaderInput
{
float3 pos : POSITION; // Incoming position of vertex
float3 color : COLOR; // Incoming color for the vertex
};
struct PixelShaderInput
{
float4 pos : SV_Position; // Copy the vertex position.
float4 color : COLOR; // Pass the color to the pixel shader.
};
PixelShaderInput main(VertexShaderInput input)
{
PixelShaderInput vertexShaderOutput;
// shader source code
return vertexShaderOutput;
}
Код построителя текстуры HLSL
// Collect input from the vertex shader.
// The COLOR semantic must match the semantic in the vertex shader code.
struct PixelShaderInput
{
float4 pos : SV_Position;
float4 color : COLOR; // Color for the pixel
};
// Set the pixel color value for the renter target.
float4 main(PixelShaderInput input) : SV_Target
{
return input.color;
}
Примеры переноса кода отрисовки OpenGL в Direct3D
Здесь мы продемонстрируем пример отрисовки в коде OpenGL ES 2.0 и эквивалентный пример в коде Direct3D 11.
Код отрисовки OpenGL
// Bind shaders to the pipeline.
// Both vertex shader and fragment shader are in a program.
glUseProgram(m_shader->getProgram());
// Input asssembly
// Get the position and color attributes of the vertex.
m_positionLocation = glGetAttribLocation(m_shader->getProgram(), "position");
glEnableVertexAttribArray(m_positionLocation);
m_colorLocation = glGetAttribColor(m_shader->getProgram(), "color");
glEnableVertexAttribArray(m_colorLocation);
// Bind the vertex buffer object to the input assembler.
glBindBuffer(GL_ARRAY_BUFFER, m_geometryBuffer);
glVertexAttribPointer(m_positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer);
glVertexAttribPointer(m_colorLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Draw a triangle with 3 vertices.
glDrawArray(GL_TRIANGLES, 0, 3);
Код отрисовки Direct3D
// Bind the vertex shader and pixel shader to the pipeline.
m_d3dDeviceContext->VSSetShader(vertexShader.Get(),nullptr,0);
m_d3dDeviceContext->PSSetShader(pixelShader.Get(),nullptr,0);
// Declare the inputs that the shaders expect.
m_d3dDeviceContext->IASetInputLayout(inputLayout.Get());
m_d3dDeviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset);
// Set the primitive's topology.
m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Draw a triangle with 3 vertices. triangleVertices is an array of 3 vertices.
m_d3dDeviceContext->Draw(ARRAYSIZE(triangleVertices),0);
Связанные темы
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по