Справочник по GLSL-to-HLSL
Код языка шейдера OpenGL (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 |
Абстрагировано для разнообразия оборудования, среда выполнения управляет большинством ресурсов | Прямой доступ к макету оборудования; приложение может управлять ресурсами и обработкой |
Предоставляет модули более высокого уровня через сторонние библиотеки (например, simple DirectMedia Layer (SDL)) | Модули более высокого уровня, такие как Direct2D, основаны на более низких модулях для упрощения разработки для приложений Windows |
Поставщики оборудования отличаются по расширениям | Корпорация Майкрософт добавляет дополнительные функции в API универсальным образом, поэтому они не относятся к конкретному поставщику оборудования. |
GLSL и HLSL обычно отличаются следующим образом:
GLSL | HLSL |
---|---|
Процедурный, пошаговый (C like) | Объектно-ориентированное, ориентированное на данные (C++ например) |
Компиляция шейдера, интегрированная в графический API | Компилятор HLSL компилирует шейдер в промежуточное двоичное представление, прежде чем Direct3D передает его драйверу.
Обратите внимание, что это двоичное представление независимо от оборудования. Обычно он компилируется во время сборки приложения, а не во время выполнения приложения.
|
Модификаторы хранилища переменных | Буферы констант и передача данных с помощью объявлений входного макета |
Типичный тип вектора: vec2/3/4 lowp, mediump, highp |
Типичный тип вектора: float2/3/4 min10float, min16float |
текстура2D [функция] | текстура. Пример [тип данных. Функция] |
sampler2D [тип данных] | Texture2D [тип данных] |
Матрицы основных строк (по умолчанию) | Матрицы с основными столбцами (по умолчанию)
Примечание. Используйте модификатор типа row_major , чтобы изменить макет для одной переменной. Дополнительные сведения см. в разделе "Синтаксис переменной". Вы также можете указать флаг компилятора или pragma, чтобы изменить глобальное значение по умолчанию.
|
Шейдер фрагментов | Построитель текстуры |
Примечание 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 означает, что значение не предоставляется буферам констант, констант означает, что шейдер не может изменить значение. Таким образом, значение известно во время компиляции на основе инициализатора. |
В GLSL переменные без модификаторов являются просто обычными глобальными переменными, которые являются частными для каждого шейдера.
При передаче данных в текстуры (Texture2D в HLSL) и связанных с ними образцах (SamplerState в HLSL) обычно объявляются как глобальные переменные в шейдере пикселей.
Перенос типов GLSL в HLSL
Используйте эту таблицу для переноса типов GLSL в HLSL.
Тип GLSL | Тип HLSL |
---|---|
скалярные типы: float, int, bool | скалярные типы: float, int, bool также, uint, double Дополнительные сведения см. в разделе Скалярные типы. |
тип вектора
|
тип вектора
Дополнительные сведения см. в разделе "Тип вектора" и "Ключевые слова". vector также определяется как float4 (floatdef vector <float, 4> vector;). Дополнительные сведения см. в разделе "Определяемый пользователем тип". |
Тип матрицы
|
Тип матрицы
Можно также использовать тип матрицы для определения матрицы. Например: матрица <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f}; Матрица также определяется как float4x4 (типдифактная матрица <float, 4, 4> матрица;). Дополнительные сведения см. в разделе "Определяемый пользователем тип". |
квалификаторы точности для float, int, sampler
|
Типы точности
Дополнительные сведения см. в статье Скалярные типы и использование минимальной точности HLSL. |
sampler2D | Текстура2D |
samplerCube | TextureCube |
Перенос предварительно определенных глобальных переменных GLSL в HLSL
Используйте эту таблицу для переноса предварительно определенных глобальных переменных GLSL в HLSL.
Предварительно определенная глобальная переменная GLSL | Семантика HLSL |
---|---|
gl_Position Эта переменная имеет тип vec4. Позиция вершины например, gl_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 ЦВЕТ в 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 Эта переменная является логическим типом. Определяет, принадлежит ли фрагмент к примитиву переднего плана. |
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 ГЛУБИНА в 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 assembly
// 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);
См. также