Поделиться через


Справочник по 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

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

Дополнительные сведения см. в разделе Скалярные типы.

тип вектора

  • Вектор с плавающей запятой: vec2, vec3, vec4
  • Логический вектор: bvec2, bvec3, bvec4
  • подписанный целочисленный вектор: ivec2, ivec3, ivec4

тип вектора

  • float2, float3, float4 и float1
  • bool2, bool3, bool4 и bool1
  • int2, int3, int4 и int1
  • Эти типы также имеют векторные расширения, аналогичные float, bool и int:

    • uint
    • min10float, min16float
    • min12int, min16int
    • min16uint

Дополнительные сведения см. в разделе "Тип вектора" и "Ключевые слова".

vector также определяется как float4 (floatdef vector <float, 4> vector;). Дополнительные сведения см. в разделе "Определяемый пользователем тип".

Тип матрицы

  • mat2: матрица с плавающей запятой 2x2
  • mat3: матрица с плавающей запятой 3x3
  • mat4: матрица с плавающей запятой 4x4

Тип матрицы

  • float2x2
  • float3x3
  • float4x4
  • также, float1x1, float1x2, float1x3, float1x4, float2x1, float2x3, float2x4, float3x1, float3x2, float3x4, float4x1, float4x2, float4x3
  • Эти типы также имеют расширения матрицы, аналогичные float:

    • int, uint, bool
    • min10float, min16float
    • min12int, min16int
    • min16uint

Можно также использовать тип матрицы для определения матрицы.

Например: матрица <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f};

Матрица также определяется как float4x4 (типдифактная матрица <float, 4, 4> матрица;). Дополнительные сведения см. в разделе "Определяемый пользователем тип".

квалификаторы точности для float, int, sampler

  • highp

    Этот квалификатор предоставляет минимальные требования к точности, превышающие значения, предоставляемые min16float и менее полного 32-разрядного с плавающей запятой. Эквивалентен в HLSL:

    highp float -> float

    highp int -> int

  • mediump

    Этот квалификатор применяется к плавающему и инту эквивалентно min16float и min12int в HLSL. Минимум 10 бит мантисса, а не как min10float.

  • низкий уровень

    Этот квалификатор, применяемый к плавающей запятой, предоставляет диапазон с плавающей запятой от -2 до 2. Эквивалент min10float в HLSL.

Типы точности

  • min16float: минимальное 16-разрядное значение с плавающей запятой
  • min10float

    Минимальное фиксированное значение со знаком 2,8 бита (2 бита целого числа и 8 бит дробного компонента). 8-разрядный дробный компонент может включать 1 вместо монопольного, чтобы дать ему полный диапазон от -2 до 2.

  • min16int: минимальное 16-разрядное целое число со знаком
  • min12int: минимальное 12-разрядное целое число со знаком

    Этот тип предназначен для 10Level9 (9_x уровней компонентов), в которых целые числа представлены числами с плавающей запятой. Это точность, получаемая при эмулации целого числа с 16-разрядным числом с плавающей запятой.

  • min16uint: минимальное 16-разрядное целое число без знака

Дополнительные сведения см. в статье Скалярные типы и использование минимальной точности 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);