Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Convertire il codice OpenGL Shader Language (GLSL) nel codice Microsoft High Level Shader Language (HLSL) quando si converte l'architettura grafica da OpenGL ES 2.0 a Direct3D 11 per creare un gioco per piattaforma UWP (Universal Windows Platform). Il GLSL a cui si fa riferimento in questo documento è compatibile con OpenGL ES 2.0; HLSL è compatibile con Direct3D 11. Per informazioni sulle differenze tra Direct3D 11 e le versioni precedenti di Direct3D, vedere Mapping delle funzionalità.
- Confronto tra OpenGL ES 2.0 e Direct3D 11
- Conversione di variabili GLSL in HLSL
- Conversione di tipi GLSL in HLSL
- Conversione di variabili globali predefinite GLSL in HLSL
- Esempi di conversione di variabili GLSL in HLSL
- Esempi di conversione del codice di rendering OpenGL in Direct3D
- Argomenti correlati
Confronto tra OpenGL ES 2.0 e Direct3D 11
OpenGL ES 2.0 e Direct3D 11 condividono molte caratteristiche. Entrambi hanno pipeline di rendering e funzionalità grafiche simili. Ma Direct3D 11 è un'implementazione del rendering e un'API, non una specifica; OpenGL ES 2.0 è una specifica di rendering e un'API, non un'implementazione. Direct3D 11 e OpenGL ES 2.0 in genere differiscono in questi modi:
OpenGL ES 2.0 | Direct3D 11 |
---|---|
Specifica indipendente dall'hardware e dal sistema operativo con implementazioni direttamente dal fornitore | Implementazione Microsoft dell'astrazione hardware e certificazione nelle piattaforme Windows |
Astratto per diversità hardware, il runtime gestisce la maggior parte delle risorse | Accesso diretto al layout hardware; l'app può gestire le risorse e l'elaborazione |
Fornisce moduli di livello superiore tramite librerie di terze parti (ad esempio Simple DirectMedia Layer, SDL) | I moduli di livello superiore, ad esempio Direct2D, sono basati su moduli inferiori per semplificare lo sviluppo per le app di Windows |
I fornitori di hardware si differenziano per via delle estensioni | Microsoft aggiunge funzionalità facoltative all'API in modo generico, in modo che non siano specifiche di alcun fornitore hardware |
GLSL e HLSL in genere differiscono in questi modi:
GLSL | HLSL |
---|---|
Procedurale, incentrato sui passaggi (come C) | Orientato agli oggetti, incentrato sui dati (come C++) |
Compilazione shader integrata nell'API grafica | Il compilatore HLSL compila lo shader in una rappresentazione binaria intermedia prima che Direct3D lo passi al driver.
Nota Questa rappresentazione binaria è indipendente dall'hardware. In genere viene compilato in fase di compilazione, anziché in fase di runtime.
|
Modificatori di archiviazione variabili | Buffer costanti e trasferimenti di dati tramite dichiarazioni di layout di input |
Tipo di vettore tipico: vec2/3/4 lowp, mediump, highp |
Tipo vettore tipico: float2/3/4 min10float, min16float |
texture2D [Function] | texture.Sample [datatype.Function] |
sampler2D [datatype] | Texture2D [datatype] |
Matrici principali di riga (impostazione predefinita) | Matrici principali di colonna (impostazione predefinita)
Nota Usare il modificatore di tipo row_major per modificare il layout per una variabile. Per maggiori informazioni, vedere Sintassi delle variabili. È anche possibile specificare un flag del compilatore o un pragma per modificare l'impostazione predefinita globale.
|
Fragment shader | Pixel shader |
Nota HLSL include texture e campionatori come due oggetti separati. In GLSL, ad esempio Direct3D 9, l'associazione di texture fa parte dello stato del campionatore.
In GLSL gran parte dello stato OpenGL viene presentato in forma di variabili globali predefinite. Ad esempio, con GLSL si usa la variabile gl_Position per specificare la posizione dei vertici e la variabile gl_FragColor per specificare il colore del frammento. In HLSL si passa lo stato Direct3D in modo esplicito dal codice dell'app allo shader. Ad esempio, con Direct3D e HLSL, l'input per il vertex shader deve corrispondere al formato dei dati nel buffer dei vertici e la struttura di un buffer costante nel codice dell'app deve corrispondere alla struttura di un buffer costante (cbuffer) nel codice dello shader.
Conversione di variabili GLSL in HLSL
In GLSL si applicano modificatori (qualificatori) a una dichiarazione di variabile shader globale per assegnare a tale variabile un comportamento specifico negli shader. In HLSL non sono necessari questi modificatori perché si definisce il flusso dello shader con gli argomenti passati allo shader e restituiti dallo shader.
Comportamento delle variabili GLSL | Equivalente HLSL |
---|---|
uniform Si passa una variabile uniforme dal codice dell'app in uno o entrambi i vertex shader e fragment shader. È necessario impostare i valori di tutte le uniformi prima di disegnare qualsiasi triangolo con tali shader in modo che i relativi valori rimangano invariati durante il disegno di una mesh di triangoli. Questi valori sono uniformi. Alcune uniformi sono impostate per l'intero frame e altre in modo univoco su una particolare coppia vertex-pixel shader. Le variabili uniformi sono variabili per poligono. |
Usare il buffer costante. Vedere Procedura: Creare un buffer costante e costanti shader. |
varying Inizializzare una variabile varying all'interno del vertex shader e passarla a una variabile varying con nome identico nel frammento shader. Poiché il vertex shader imposta solo il valore delle variabili varying in ogni vertice, il rasterizzatore interpola tali valori (in modo prospetticamente corretto) per generare valori per frammento da passare al fragment shader. Queste variabili variano in ogni triangolo. |
Usare la struttura restituita dal vertex shader come input per il pixel shader. Assicurarsi che i valori semantici corrispondano. |
attribute Un attributo fa parte della descrizione di un vertice passato dal codice dell'app al vertex shader da solo. A differenza di un'uniforme, si imposta il valore di ogni attributo per ogni vertice, che a sua volta consente a ogni vertice di avere un valore diverso. Le variabili di attributo sono variabili per vertice. |
Definire un buffer dei vertici nel codice dell'app Direct3D e abbinarlo all'input del vertice definito nel vertex shader. Facoltativamente, definire un buffer degli indici. Vedere Procedura: Creare un vertex Buffer e Procedura: Creare un buffer degli indici. Creare un layout di input nel codice dell'app Direct3D e associare i valori semantici a quelli nell'input del vertice. Vedere Creare il layout di input. |
const Costanti compilate nello shader e che non cambiano mai. |
Usare un const statico. static indica che il valore non è esposto ai buffer costanti, const significa che lo shader non può modificare il valore. Pertanto, il valore è noto in fase di compilazione in base al relativo inizializzatore. |
In GLSL le variabili senza modificatori sono solo variabili globali normali private per ogni shader.
Quando si passano i dati alle texture (Texture2D in HLSL) e ai relativi campionatori associati (SamplerState in HLSL), in genere li si dichiara come variabili globali nel pixel shader.
Conversione di tipi GLSL in HLSL
Usare questa tabella per convertire i tipi GLSL in HLSL.
Tipo di GLSL | Tipo di HLSL |
---|---|
tipi scalari: float, int, bool | tipi scalari: float, int, bool anche uint, double Per maggiori informazioni, vedere Tipi scalari. |
tipo di vettore
|
tipo di vettore
Per maggiori informazioni, vedere Tipo di vettore e Parole chiave. vector è anche un tipo definito come float4 (typedef vector <float, 4> vector;). Per maggiori informazioni, vedere Tipo definito dall'utente. |
tipo matrice
|
tipo matrice
È anche possibile usare il tipo matrice per definire una matrice. Ad esempio: matrix <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f}; matrix è anche un tipo definito come float4x4 (matrix <typedef float, 4, 4> matrix;). Per maggiori informazioni, vedere Tipo definito dall'utente. |
qualificatori di precisione per float, int, sampler
|
tipi di precisione
Per maggiori informazioni, vedere Tipi scalari e Uso della precisione minima HLSL. |
sampler2D | Texture2D |
samplerCube | TextureCube |
Conversione di variabili globali predefinite GLSL in HLSL
Usare questa tabella per convertire le variabili globali predefinite GLSL in HLSL.
Variabile globale predefinita GLSL | Semantica HLSL |
---|---|
gl_Position Questa variabile è di tipo vec4. Posizione del vertice ad esempio - gl_Position = position; |
SV_Position POSITION in Direct3D 9 Questa semantica è di tipo float4. Output del vertex shader Posizione del vertice ad esempio - float4 vPosition : SV_Position; |
gl_PointSize Questa variabile è di tipo float. Dimensione del punto |
PSIZE Nessun significato a meno di non destinare a Direct3D 9 Questa semantica è di tipo float. Output del vertex shader Dimensione del punto |
gl_FragColor Questa variabile è di tipo vec4. Colore del frammento ad esempio - gl_FragColor = vec4(colorVarying, 1,0); |
SV_Target COLOR in Direct3D 9 Questa semantica è di tipo float4. Output del pixel shader Colore del pixel ad esempio - float4 Color[4] : SV_Target; |
gl_FragData[n] Questa variabile è di tipo vec4. Colore del frammento per l'allegato colore n |
SV_Target[n] Questa semantica è di tipo float4. Valore di output del pixel shader archiviato in destinazione di rendering n, dove 0 <= n <= 7. |
gl_FragCoord Questa variabile è di tipo vec4. Posizione del frammento all'interno del buffer di frame |
SV_Position Non disponibile in Direct3D 9 Questa semantica è di tipo float4. Input del pixel shader Coordinate dello spazio dello schermo ad esempio - float4 screenSpace : SV_Position |
gl_FrontFacing Questa variabile è di tipo bool. Determina se il frammento appartiene a una primitiva rivolta verso il lato anteriore. |
SV_IsFrontFace VFACE in Direct3D 9 SV_IsFrontFace è di tipo bool. VFACE è di tipo float. Input del pixel shader Direzione della primitiva |
gl_PointCoord Questa variabile è di tipo vec2. Posizione del frammento all'interno di un punto (solo rasterizzazione del punto) |
SV_Position VPOS in Direct3D 9 SV_Position è di tipo float4. VPOS è di tipo float2. Input del pixel shader Posizione del pixel o del campione nello spazio dello schermo ad esempio - float4 pos : SV_Position |
gl_FragDepth Questa variabile è di tipo float. Dati del buffer di profondità |
SV_Depth DEPTH in Direct3D 9 SV_Depth è di tipo float. Output del pixel shader Dati del buffer di profondità |
Si usa la semantica per specificare la posizione, il colore e così via per l'input del vertex shader e del pixel shader. È necessario corrispondere ai valori semantici nel layout di input con l'input del vertex shader. Per esempi, vedere Esempi di conversione di variabili GLSL in HLSL. Per maggiori informazioni sulla semantica HLSL, vedere Semantica.
Esempi di conversione di variabili GLSL in HLSL
Di seguito vengono illustrati esempi di uso delle variabili GLSL nel codice OpenGL/GLSL e quindi dell'esempio equivalente nel codice Direct3D/HLSL.
Uniform, attribute e varying in GLSL
Codice app 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;
Codice vertex shader 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
}
Codice del fragment shader 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);
}
Buffer costanti e trasferimenti di dati in HLSL
Di seguito è riportato un esempio di come si passano dati al vertex shader HLSL che passa quindi attraverso il pixel shader. Nel codice dell'app, definire un vertice e un buffer costante. Quindi, nel codice del vertex shader, definire il buffer costante come cbuffer e archiviare i dati per vertice e i dati di input del pixel shader. Qui si usano strutture chiamate VertexShaderInput e PixelShaderInput.
Codice app 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.
Codice vertex shader 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;
}
Codice pixel shader 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;
}
Esempi di conversione del codice di rendering OpenGL in Direct3D
Di seguito viene illustrato un esempio di rendering nel codice OpenGL ES 2.0 e quindi nell'esempio equivalente nel codice Direct3D 11.
Codice di rendering 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);
Codice di rendering 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);
Argomenti correlati