Fazer a portabilidade do GLSLPort the GLSL

APIs importantesImportant APIs

Quando você tiver movido o código que cria e configura os seus buffers e objetos de sombreador, será o momento de fazer a portabilidade do código dentro dos sombreadores da linguagem de sombreadores GL do OpenGL ES 2.0 (GLSL) para a linguagem de sombreadores de alto nível do Direct3D 11 (HLSL).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).

No OpenGL ES 2,0, os sombreadores retornam dados após a execução usando intrínsecos como a ** _ posição GL**, GL _ FragColorou **GL _ FragData [ n ] ** (em que n é o índice de um destino de renderização específico).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). No Direct3D, não há intrínsecos específicos e os sombreadores devolvem dados como o tipo de retorno das duas respectivas funções principais().In Direct3D, there are no specific intrinsics, and the shaders return data as the return type of their respective main() functions.

Dados que você quer interpolados entre estágios de sombreador, como a posição do vértice ou normal, são manipulados pelo uso da declaração 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. Entretanto, o Direct3D não tem essa declaração. Em vez disso, cada dado que você quer que passe entre os estágios de sombreador devem ser marcados com uma semântica 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. A semântica específica selecionada indica (e é) a finalidade dos dados.The specific semantic chosen indicates the purpose of the data, and is. Por exemplo, você deve declarar os dados que deseja interpolar entre o sombreador de fragmento como:For example, you'd declare vertex data that you want interpolated between the fragment shader as:

float4 vertPos : POSITION;

ouor

float4 vertColor : COLOR;

Onde POSITION é a semântica usada para indicar dados de posição de vértice.Where POSITION is the semantic used to indicate vertex position data. POSITION também é um caso especial, pois, após a interpolação, ele não pode ser acessado pelo sombreador de pixel.POSITION is also a special case, since after interpolation, it cannot be accessed by the pixel shader. Portanto, você deve especificar a entrada para o sombreador de pixel com a _ posição da VA e os dados de vértice interpolados serão colocados nessa variável.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;

A semântica pode ser declarada nos métodos de corpo (principais) dos sombreadores.Semantics can be declared on the body (main) methods of shaders. Para sombreadores de pixel, _ a VA Target [ n ] , que indica um destino de renderização, é necessária no método Body.For pixel shaders, SV_TARGET[n], which indicates a render target, is required on the body method. (VA _ O destino sem um sufixo numérico é padronizado para renderizar o índice de destino 0.)(SV_TARGET without a numeric suffix defaults to render target index 0.)

Observe também que os sombreadores de vértice são necessários para produzir a semântica de valor do sistema da posição da VA _ .Also note that vertex shaders are required to output the SV_POSITION system value semantic. Essa semântica resolve os dados de posição de vértice para valores de coordenadas nos casos em que x fica entre -1 e 1, y fica entre -1 e 1, z é dividido pelo valor de w da coordenada homogênea original (z/w) e w é 1 dividido pelo valor original de w (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). Os sombreadores de pixel usam a semântica de valor do sistema de posição da VA _ para recuperar o local do pixel na tela, em que x está entre 0 e a largura do destino de renderização e y está entre 0 e a altura de destino de renderização (cada deslocamento por 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). _Os sombreadores de nível de recurso 9 x de pixel não podem ler o valor da posição da VA _ .Feature level 9_x pixel shaders cannot read from the SV_POSITION value.

Buffers constantes devem ser declarados com cbuffer e associados a um registro de inicialização específico para pesquisa.Constant buffers must be declared with cbuffer and be associated with a specific starting register for lookup.

Direct3D 11: declaração de buffer constante HLSLDirect3D 11: An HLSL constant buffer declaration

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

Aqui, o buffer constante usa registro b0 para colocar em espera o buffer em pacote.Here, the constant buffer uses register b0 to hold the packed buffer. Todos os registros são referidos na forma b # .All registers are referred to in the form b#. Para saber mais sobre a implementação HLSL de buffers constantes, registros e remessa de dados, leia Shader Constants (HLSL).For more information on the HLSL implementation of constant buffers, registers, and data packing, read Shader Constants (HLSL).

InstruçõesInstructions

Etapa 1: compatibilizar o sombreador de vérticeStep 1: Port the vertex shader

No nosso exemplo simples de OpenGL ES 2.0, o sombreador de vértice tem três entradas: uma matriz 4x4 de projeção de exibição constante de modelo e dois vetores de 4 coordenadas.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. Esses dois vetores contêm a posição do vértice e sua cor.These two vectors contain the vertex position and its color. O sombreador transforma o vetor de posição em coordenadas de perspectiva e a atribui à _ posição GL intrínseca para rasterização.The shader transforms the position vector to perspective coordinates and assigns it to the gl_Position intrinsic for rasterization. A cor de vértice é copiada para uma variável, que varia, para interpolação durante a rasterização também.The vertex color is copied to a varying variable for interpolation during rasterization, as well.

OpenGL ES 2.0: sombreador de vértice para objeto de 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;
}

No Direct3D, a matriz constante de modelo-exibição-projeção está contida em um buffer constante, empacotado no Registro b0, e a posição e cor do vértice são marcadas especificamente com a semântica HLSL apropriada: 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. Como o layout de entrada indica uma ordem específica desses dois valores de vértice, crie uma estrutura para armazená-los e declare-a como o tipo do parâmetro de entrada na função (principal) do corpo do sombreadorSince 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). (Você também pode especificá-los como dois parâmetros individuais, mas isso pode ser problemático). Você também especifica um tipo de saída para esse estágio, que contém a cor e a posição interpoladas, e declará-la como o valor de retorno para a função do corpo do sombreador de vértice.(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: sombreador de vértice para objeto de 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;
}

O tipo de dados de saída, PixelShaderInput, é populado durante a rasterização e fornecido ao sombreador de fragmento (pixel).The output data type, PixelShaderInput, is populated during rasterization and provided to the fragment (pixel) shader.

Etapa 2: compatibilizar o sombreador de fragmentoStep 2: Port the fragment shader

Nosso sombreador de fragmento de exemplo em GLSL é extremamente simples: forneça o GL _ FragColor intrínseco com o valor de cor interpolado.Our example fragment shader in GLSL is extremely simple: provide the gl_FragColor intrinsic with the interpolated color value. O OpenGL ES 2.0 o reescreverá no destino de renderização padrão.OpenGL ES 2.0 will write it to the default render target.

OpenGL ES 2.0: sombreador de fragmento para objeto de cubo (GLSL)OpenGL ES 2.0: Fragment shader for the cube object (GLSL)

varying vec4 destColor;

void main()
{
  gl_FragColor = destColor;
} 

O Direct3D é quase tão simples quanto o OpenGL ES 2.0.Direct3D is almost as simple. A única diferença importante é que a função do corpo do sombreador de pixel deve retornar um valor.The only significant difference is that the body function of the pixel shader must return a value. Como a cor é um valor float de 4 coordenadas (RGBA), você indica FLOAT4 como o tipo de retorno e, em seguida, especifica o destino de renderização padrão como a semântica de valor do sistema de destino da VA _ .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: sombreador de pixel para o objeto 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);
}

A cor do pixel na posição é gravada no destino de renderização.The color for the pixel at the position is written to the render target. Agora, vamos ver como exibir os conteúdos daquele destino de renderização em Desenhar na tela!Now, let's see how to display the contents of that render target in Draw to the screen!

Etapa anteriorPrevious step

Fazer a portabilidade de buffers de vértices e dados Próxima etapaPort the vertex buffers and data Next step

Desenhar na tela ObservaçõesDraw to the screen Remarks

Entender a semântica HLSL e o compactação de buffers constantes pode evitar certa dor de cabeça, e oferecer oportunidade de otimização.Understanding HLSL semantics and the packing of constant buffers can save you a bit of a debugging headache, as well as provide optimization opportunities. Caso tenha chance, leia Sintaxe variável (HLSL), Introdução a buffers no Direct3D 11 e Como: criar um buffer constante.If you get a chance, read through Variable Syntax (HLSL), Introduction to Buffers in Direct3D 11, and How to: Create a Constant Buffer. Caso não consiga fazer isso, consulte algumas dicas iniciais sobre semântica e buffers constantes para ter sempre em mente:If not, though, here's a few starting tips to keep in mind about semantics and constant buffers:

  • Sempre confira duas vezes o código da configuração Direct3D do renderizador para garantir que: as estruturas dos buffers constantes correspondam às declarações da estrutura cbuffer no HLSL; e que os tipos escalares do componente coincidam em ambas as declarações.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.
  • No código C++ do renderizador, use os tipos DirectXMath nas declarações de buffer constante para garantir o empacotamento correto dos dados.In your renderer's C++ code, use DirectXMath types in your constant buffer declarations to ensure proper data packing.
  • O melhor modo de usar buffers constantes de modo eficiente é organizar as variáveis de sombreador em buffers constantes com base na frequência de atualização.The best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. Por exemplo, caso tenha alguns dados uniformes atualizados uma vez por quadro e outros atualizados somente quando a câmera se move, talvez seja o caso de separar os dados em dois buffers constantes distintos.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.
  • Os primeiros erros de origem de compilação de sombreador (FXC) serão gerados pela semântica que você se esqueceu de aplicar ou aplicada incorretamente.Semantics that you have forgotten to apply or which you have applied incorrectly will be your earliest source of shader compilation (FXC) errors. Confira-as com atenção!Double-check them! Os documentos podem ser um pouco confusos, pois muitas páginas e exemplos antigos mencionam versões diferentes da semântica HLSL, anteriores ao 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.
  • Certifique-se de que sabe qual nível de recurso do Direct3D você tem como objetivo para cada sombreador.Make sure you know which Direct3D feature level you are targeting for each shader. A semântica para o nível de recurso 9 _ * é diferente daquelas para 11 _ 1.The semantics for feature level 9_* are different from those for 11_1.
  • A semântica da posição da VA _ resolve os dados de posição pós-interpolação associados para coordenar valores em que x está entre 0 e a largura de destino de renderização, y está entre 0 e a altura de destino de renderização, z é dividido pelo valor original de coordenada original (z/w) e w é 1 dividido pelo valor de w inicial (1/w).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).

Como: compatibilizar um renderizador simples do OpenGL ES 2.0 ao Direct3D 11How to: port a simple OpenGL ES 2.0 renderer to Direct3D 11

Compatibilizar os objetos de sombreadoresPort the shader objects

Fazer a portabilidade de dados e buffers de vérticesPort the vertex buffers and data

Desenhar na telaDraw to the screen