Convertire il codice GLSLPort the GLSL

API importantiImportant APIs

Dopo la migrazione del codice che crea e configura i buffer e gli oggetti shader, convertiamo il codice all’interno degli shader da OpenGL ES 2.0 a Direct3D 11.Once you've moved over the code that creates and configures your buffers and shader objects, it's time to port the code inside those shaders from OpenGL ES 2.0's GL Shader Language (GLSL) to Direct3D 11's High-level Shader Language (HLSL).

In OpenGL ES 2,0 gli shader restituiscono i dati dopo l'esecuzione usando oggetti intrinseci come la ** _ posizione GL**, GL _ FragColoro **GL _ FragData [ n ] ** (dove n è l'indice per una destinazione di rendering specifica).In OpenGL ES 2.0, shaders return data after execution using intrinsics such as gl_Position, gl_FragColor, or gl_FragData[n] (where n is the index for a specific render target). In Direct3D non esistono valori intrinseci specifici e gli shader restituiscono dati come tipo restituito delle rispettive funzioni main().In Direct3D, there are no specific intrinsics, and the shaders return data as the return type of their respective main() functions.

I dati che vuoi interpolare tra le varie fasi degli shader, come la posizione dei vertici o la normale, vengono gestiti tramite l’uso della dichiarazione varying.Data that you want interpolated between shader stages, such as the vertex position or normal, is handled through the use of the varying declaration. Direct3D non include però questa dichiarazione. Gli eventuali dati che vuoi passare tra le fasi degli shader devono essere contrassegnati con una semantica HLSL.However, Direct3D doesn't have this declaration; rather, any data that you want passed between shader stages must be marked with an HLSL semantic. La specifica semantica scelta indica lo scopo dei dati.The specific semantic chosen indicates the purpose of the data, and is. Ad esempio, questo è il modo in cui potresti dichiarare i dati dei vertici che vuoi interpolare per il fragment shader:For example, you'd declare vertex data that you want interpolated between the fragment shader as:

float4 vertPos : POSITION;

oppureor

float4 vertColor : COLOR;

Dove POSITION è la semantica usata per indicare i dati di posizione dei vertici.Where POSITION is the semantic used to indicate vertex position data. POSITION è anche un caso speciale, perché dopo l'interpolazione non è accessibile per il pixel shader.POSITION is also a special case, since after interpolation, it cannot be accessed by the pixel shader. Pertanto, è necessario specificare l'input per la pixel shader con la _ posizione SV e i dati dei vertici interpolati verranno posizionati in tale variabile.Therefore, you must specify input to the pixel shader with SV_POSITION and the interpolated vertex data will be placed in that variable.

float4 position : SV_POSITION;

Le semantiche possono essere dichiarate nei metodi centrali (main) degli shader.Semantics can be declared on the body (main) methods of shaders. Per i pixel shader, SV _ target [ n ] , che indica una destinazione di rendering, è obbligatorio per il metodo Body.For pixel shaders, SV_TARGET[n], which indicates a render target, is required on the body method. (SV _ Il valore predefinito della destinazione senza suffisso numerico è l'indice della destinazione di rendering 0.(SV_TARGET without a numeric suffix defaults to render target index 0.)

Si noti inoltre che i vertex shader sono necessari per restituire la _ semantica del valore del sistema di posizione SV.Also note that vertex shaders are required to output the SV_POSITION system value semantic. Questa semantica converte i dati di posizione dei vertici in valori di coordinate, dove x è un valore compreso tra -1 e 1, y è un valore compreso tra -1 e 1, z viene diviso per il valore w originale delle coordinate omogenee (z/w) e w corrisponde a 1 diviso per il valore w originale (1/w).This semantic resolves the vertex position data to coordinate values where x is between -1 and 1, y is between -1 and 1, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w). I pixel shader utilizzano la _ semantica del valore del sistema di posizione SV per recuperare la posizione dei pixel sullo schermo, dove x è compreso tra 0 e la larghezza della destinazione di rendering e y è compresa tra 0 e l'altezza della destinazione di rendering (ogni offset di 0,5).Pixel shaders use the SV_POSITION system value semantic to retrieve the pixel location on the screen, where x is between 0 and the render target width and y is between 0 and the render target height (each offset by 0.5). Il livello di funzionalità 9 _ x pixel shader non è in grado di leggere il _ valore di posizione SV.Feature level 9_x pixel shaders cannot read from the SV_POSITION value.

I buffer costanti devono essere dichiarati con cbuffer e associati a un registro iniziale specifico per la ricerca.Constant buffers must be declared with cbuffer and be associated with a specific starting register for lookup.

Direct3D 11: dichiarazione di un buffer costante HLSLDirect3D 11: An HLSL constant buffer declaration

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

In questo esempio il buffer costante usa il registro b0 per il buffer compresso.Here, the constant buffer uses register b0 to hold the packed buffer. A tutti i registri viene fatto riferimento nel formato b # .All registers are referred to in the form b#. Per altre informazioni sull’implementazione HLSL dei buffer costanti, sui registri e sulla compressione dei dati, vedi l’articolo dedicato alle costanti degli shader (HLSL).For more information on the HLSL implementation of constant buffers, registers, and data packing, read Shader Constants (HLSL).

IstruzioniInstructions

Passaggio 1: Convertire il vertex shaderStep 1: Port the vertex shader

Nel nostro semplice esempio OpenGL ES 2.0, il vertex shader ha tre input: una matrice 4x4 model-view-projection costante e due vettori da 4 coordinate.In our simple OpenGL ES 2.0 example, the vertex shader has three inputs: a constant model-view-projection 4x4 matrix, and two 4-coordinate vectors. I due vettori contengono la posizione del vertice e il relativo colore.These two vectors contain the vertex position and its color. Lo shader trasforma il vettore di posizione in coordinate prospettiche e lo assegna alla _ posizione GL intrinseca per la rasterizzazione.The shader transforms the position vector to perspective coordinates and assigns it to the gl_Position intrinsic for rasterization. Anche il colore del vertice viene copiato in una variabile varying per l'interpolazione durante la rasterizzazione.The vertex color is copied to a varying variable for interpolation during rasterization, as well.

OpenGL ES 2.0: vertex shader per l'oggetto cubo (GLSL)OpenGL ES 2.0: Vertex shader for the cube object (GLSL)

uniform mat4 u_mvpMatrix; 
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 destColor;

void main()
{           
  gl_Position = u_mvpMatrix * a_position;
  destColor = a_color;
}

In Direct3D, la matrice model-view-projection di costanti è ora contenuta in un buffer costante compresso nel registro b0 e la posizione e il colore del vertice sono contrassegnati in modo esplicito con le rispettive semantiche HLSL appropriate: POSITION e COLOR.Now, in Direct3D, the constant model-view-projection matrix is contained in a constant buffer packed at register b0, and the vertex position and color are specifically marked with the appropriate respective HLSL semantics: POSITION and COLOR. Dato che il nostro layout di input indica una disposizione specifica di questi due valori del vertice, devi creare uno struct per contenerli e dichiararlo come il tipo per il parametro di input nella funzione principale dello shader (main).Since our input layout indicates a specific arrangement of these two vertex values, you create a struct to hold them and declare it as the type for the input parameter on the shader body function (main). (Potresti anche specificarli come due singoli parametri, ma potrebbe diventare complicato.) Devi anche specificare un tipo di output per questa fase, che contiene la posizione e il colore interpolati, quindi dichiaralo come valore restituito per la funzione principale del vertex shader.(You could also specify them as two individual parameters, but that could get cumbersome.) You also specify an output type for this stage, which contains the interpolated position and color, and declare it as the return value for the body function of the vertex shader.

Direct3D 11: vertex shader per l'oggetto cubo (HLSL)Direct3D 11: Vertex shader for the cube object (HLSL)

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

// Per-vertex data used as input to the vertex shader.
struct VertexShaderInput
{
  float3 pos : POSITION;
  float3 color : COLOR;
};

// Per-vertex color data passed through the pixel shader.
struct PixelShaderInput
{
  float3 pos : SV_POSITION;
  float3 color : COLOR;
};

PixelShaderInput main(VertexShaderInput input)
{
  PixelShaderInput output;
  float4 pos = float4(input.pos, 1.0f); // add the w-coordinate

  pos = mul(mvp, projection);
  output.pos = pos;

  output.color = input.color;

  return output;
}

Il tipo di dati di output, PixelShaderInput, viene popolato durante la rasterizzazione e fornito al fragment (pixel) shader.The output data type, PixelShaderInput, is populated during rasterization and provided to the fragment (pixel) shader.

Passaggio 2: Convertire il fragment shaderStep 2: Port the fragment shader

Il frammento di esempio shader in GLSL è estremamente semplice: fornire l'oggetto GL _ FragColor intrinseco con il valore del colore interpolato.Our example fragment shader in GLSL is extremely simple: provide the gl_FragColor intrinsic with the interpolated color value. OpenGL ES 2.0 lo scriverà nella destinazione di rendering predefinita.OpenGL ES 2.0 will write it to the default render target.

OpenGL ES 2.0: fragment shader per l'oggetto cubo (GLSL)OpenGL ES 2.0: Fragment shader for the cube object (GLSL)

varying vec4 destColor;

void main()
{
  gl_FragColor = destColor;
} 

Direct3D è quasi altrettanto semplice.Direct3D is almost as simple. L'unica differenza significativa è che la funzione principale del pixel shader deve restituire un valore.The only significant difference is that the body function of the pixel shader must return a value. Poiché il colore è un valore float a 4 Coordinate (RGBA), si indica float4 come tipo restituito, quindi si specifica la destinazione di rendering predefinita come _ semantica del valore del sistema di destinazione Sv.Since the color is a 4-coordinate (RGBA) float value, you indicate float4 as the return type, and then specify the default render target as the SV_TARGET system value semantic.

Direct3D 11: pixel shader per l'oggetto cubo (HLSL)Direct3D 11: Pixel shader for the cube object (HLSL)

struct PixelShaderInput
{
  float4 pos : SV_POSITION;
  float3 color : COLOR;
};


float4 main(PixelShaderInput input) : SV_TARGET
{
  return float4(input.color, 1.0f);
}

Il colore per il pixel nella posizione viene scritto nella destinazione di rendering.The color for the pixel at the position is written to the render target. Vediamo ora come visualizzare il contenuto di tale destinazione di rendering in Disegnare sullo schermo!Now, let's see how to display the contents of that render target in Draw to the screen!

Passaggio precedentePrevious step

Convertire i buffer dei vertici e i dati Passaggio successivoPort the vertex buffers and data Next step

Disegnare sullo schermo OsservazioniDraw to the screen Remarks

La conoscenza delle semantiche HLSL e della compressione dei buffer costanti può risparmiarti molto lavoro di debug, oltre a offrire opportunità di ottimizzazione.Understanding HLSL semantics and the packing of constant buffers can save you a bit of a debugging headache, as well as provide optimization opportunities. Se puoi, dedica un po’ di tempo alla lettura degli articoli relativi alla sintassi delle variabili (HLSL), all’introduzione ai buffer in Direct3D 11 e alla procedura per creare un buffer costante.If you get a chance, read through Variable Syntax (HLSL), Introduction to Buffers in Direct3D 11, and How to: Create a Constant Buffer. In caso contrario, ecco alcuni suggerimenti iniziali da tenere presenti in merito alle semantiche e ai buffer costanti:If not, though, here's a few starting tips to keep in mind about semantics and constant buffers:

  • Controlla sempre accuratamente il codice di configurazione Direct3D del tuo renderer per assicurarti che le strutture per i buffer costanti corrispondano alle dichiarazioni dello struct cbuffer nel codice HLSL e che i tipi scalari componenti corrispondano in entrambe le dichiarazioni.Always double check your renderer's Direct3D configuration code to make sure that the structures for your constant buffers match the cbuffer struct declarations in your HLSL, and that the component scalar types match across both declarations.
  • Nel codice C++ del tuo renderer usa i tipi DirectXMath nelle dichiarazioni del buffer costante per assicurare una compressione appropriate dei dati.In your renderer's C++ code, use DirectXMath types in your constant buffer declarations to ensure proper data packing.
  • Il modo migliore per usare in modo efficiente i buffer costanti consiste nell'organizzare le variabili dello shader in buffer costanti in base alla rispettiva frequenza di aggiornamento.The best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. Se hai dati uniform aggiornati una volta per ogni frame, ad esempio, e altri dati uniform aggiornati solo allo spostamento della fotocamera, prendi in considerazione la possibilità di dividere i dati in due buffer costanti separati.For example, if you have some uniform data that is updated once per frame, and other uniform data that is updated only when the camera moves, consider separating that data into two separate constant buffers.
  • Le semantiche che dimentichi di applicare o che applichi in modo non corretto rappresenteranno la prima fonte di errori di compilazione dello shader (FXC).Semantics that you have forgotten to apply or which you have applied incorrectly will be your earliest source of shader compilation (FXC) errors. Controllale con molta attenzione.Double-check them! La documentazione può creare un po' di confusione, dato che molte pagine e molti esempi non recenti fanno riferimento a versioni diverse delle semantiche HLSL precedenti a Direct3D 11.The docs can be a bit confusing, as many older pages and samples refer to different versions of HLSL semantics prior to Direct3D 11.
  • Assicurati di conoscere il livello di funzionalità Direct3D di destinazione per ogni shader.Make sure you know which Direct3D feature level you are targeting for each shader. La semantica per il livello di funzionalità 9 _ * è diversa da quella per 11 _ 1.The semantics for feature level 9_* are different from those for 11_1.
  • La _ semantica di posizione SV risolve i dati della posizione di post-interpolazione associata per coordinare i valori in cui x è compreso tra 0 e la larghezza della destinazione di rendering, y è compreso tra 0 e l'altezza della destinazione di rendering, z è divisa per il valore di coordinate omogenee originale w (z/w) e w è diviso per il valore w originale (1/The SV_POSITION semantic resolves the associated post-interpolation position data to coordinate values where x is between 0 and the render target width, y is between 0 and the render target height, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w).

Procedura: trasferire un renderer OpenGL ES 2,0 semplice a Direct3D 11How to: port a simple OpenGL ES 2.0 renderer to Direct3D 11

Convertire gli oggetti shaderPort the shader objects

Convertire i vertex buffer e i datiPort the vertex buffers and data

Disegnare sullo schermoDraw to the screen