GLSL 到 HLSL 参考

GLSL 到 HLSL 参考

转自http://msdn.microsoft.com/zh-cn/library/windows/apps/dn166865/html

将你的图形体系结构从 OpenGL ES 2.0 移植到 Direct3D 11 以便为 Windows 8 创建游戏时,你需要将你的 OpenGL 着色器语言 (GLSL) 代码移植到 Microsoft 高级着色器语言 (HLSL) 代码。 此处所谈到的 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.0Direct3D 11
硬件和操作系统规范与供应商提供的实现无关在 Windows 平台上硬件抽象和认证的 Microsoft 实现
对硬件多样性进行了抽象,运行时管理大多数资源直接访问硬件布局;应用可以管理资源和处理
通过第三方库(例如,Simple DirectMedia Layer (SDL))提供更高级的模块更高级的模块(如 Direct2D)构建在低级模块上,以简化 Windows 应用的开发
通过扩展名来区分硬件供应商Microsoft 采用常规方法向 API 中添加可选功能,以便这些功能不会特定于任何特定的硬件供应商

 

GLSL 和 HLSL 通常会在以下方面有所不同:

GLSLHLSL
注重过程,以步骤为中心(如 C)面向对象,以数据为中心(如 C++)
着色器编译被集成到了图形 API 中HLSL 编译器将着色器编译为中间二进制表示,然后 Direct3D 将其传递给驱动程序。

注意  此二进制表示与硬件无关。通常在应用构建时对其进行编译,而不是在应用运行时编译。

可变存储修饰符通过输入布局声明进行常量缓冲区和数据传输

类型

典型的矢量类型:vec2/3/4

lowp、mediump、highp

典型的矢量类型:float2/3/4

min10float、min16float

texture2D [Function]texture.Sample [datatype.Function]
sampler2D [datatype]Texture2D [datatype]
行主序矩阵(默认设置)列主序矩阵(默认设置)

注意  使用 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 等效内容

uniform

将 uniform 变量从应用代码传递到顶点着色器和分段着色器或传递到两者。必须在使用这些着色器绘制任何三角形之前,设置所有 uniform 的值,以便它们的值在绘制三角形网格的整个过程中保持不变。这些值都是 uniform。一些 uniform 是针对整个帧设置的,另一些 uniform 唯一对应于一个特定的顶点像素着色器对。

uniform 变量是每个多边形的变量。

使用常量缓冲区。

请参阅如何创建常量缓冲区着色器常量

varying

在顶点着色器内初始化一个 varying 变量,并将其传递到片段着色器中具有相同名称的 varying 变量。由于顶点着色器仅设置每个顶点上的 varying 变量的值,因此光栅器会插入这些值(采用透视校正的方式),以生成每个要传递到片段着色器中的片段值。这些变量在各个三角形之间有所不同。

使用从顶点着色器返回的结构作为像素着色器的输入。确保语义值相匹配。

attribute

attribute 只是你从应用代码传递到顶点着色器的顶点描述的一部分。与 uniform 不同,你为每个顶点设置每个 attribute 的值,但却允许每个顶点拥有不同的值。attribute 变量是每个顶点的变量。

在 Direct3D 应用代码中定义顶点缓冲区并将其与顶点着色器中定义的顶点输入相匹配。也可以定义索引缓冲区。请参阅如何创建顶点缓冲区如何创建索引缓冲区

在 Direct3D 应用代码中创建输入布局并将语义值与顶点输入中的值相匹配。请参阅创建输入布局

const

常量编译到着色器中,从不更改。

使用 static conststatic 表示未向常量缓冲区显示该值,const 表示着色器无法更改该值。因此,在编译时我们根据它的初始值来了解该值。

 

在 GLSL 中,没有修饰符的变量只是普通的全局变量,它们是每个着色器的私有变量。

当将数据传递到纹理(在 HLSL 中为 Texture2D)及其关联的采样器 (在 HLSL 中为 SamplerState)时,通常会在像素着色器中将它们声明为全局变量。

将 GLSL 类型移植到 HLSL

使用该表将 GLSL 类型移植到 HLSL。

GLSL 类型HLSL 类型
标量类型:float、int、bool

标量类型:float、int、bool

also、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 的 also 类型 (typedef vector <float, 4> vector;)。有关详细信息,请参阅用户定义的类型

矩阵类型

  • mat2: 2x2 浮点矩阵
  • mat3: 3x3 浮点矩阵
  • mat4: 4x4 浮点矩阵

矩阵类型

  • float2x2
  • float3x3
  • float4x4
  • also、float1x1、float1x2、float1x3、float1x4、float2x1、float2x3、float2x4、float3x1、float3x2、float3x4、float4x1、float4x2、float4x3
  • 这些类型也都有类似于 float 的矩阵扩展:

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

也可以使用矩阵类型来定义矩阵。

例如:matrix <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f};

matrix 是定义为 float4x4 的 also 类型 (typedef matrix <float, 4, 4> matrix;)。有关详细信息,请参阅用户定义的类型

float、int、sampler 的精度限定符

  • highp

    该限定符提供最低精度要求,该要求大于 min16float 提供的要求,但小于完整的 32 位浮点。 HLSL 中的等效内容为:

    highp float -> float

    highp int -> int

  • mediump

    该限定符应用于 float 和 int,它等效于 HLSL 中的 min16float 和 min12int。 最低 10 位尾数,与 min10float 不同。

  • lowp

    该限定符应用于 float,它提供的浮点范围为 -2 到 2。等效于 HLSL 中的 min10float。

精度类型

  • min16float:最低 16 位浮点值
  • min10float

    最低固定点有符号 2.8 位值(2 位整数和 8 位小数部分)。8 位小数部分可以包括 1,而非排除 1,目的是为它提供完整的包含范围 -2 到 2。

  • min16int:最低 16 位有符号整数
  • min12int:最低 12 位有符号整数

    该类型用于 10Level9(9_x 功能级别),其中整数由浮点数来表示。 这是在使用 16 位浮点数模拟整数时可以获得的精度。

  • min16uint:最低 16 位无符号整数

有关详细信息,请参阅标量类型使用 HLSL 最低精度

sampler2DTexture2D
samplerCubeTextureCube

 

将 GLSL 预定义的全局变量移植到 HLSL

使用该表将 GLSL 预定义的全局变量移植到 HLSL。

GLSL 预定义的全局变量HLSL 语义

gl_Position

该变量为 vec4 类型。

顶点位置

例如 - gl_Position = position;

SV_Position

在 Direct3D 9 中为 POSITION

该语义为 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 中为 COLOR

该语义为 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

该变量为 bool 类型。

确定片段是否属于正面基元。

SV_IsFrontFace

在 Direct3D 9 中为 VFACE

SV_IsFrontFace 为 bool 类型。

SV_IsFrontFace 为 float 类型。

像素着色器输入

基元朝向

gl_PointCoord

该变量为 vec2 类型。

某个点中的片段位置(仅限点光栅化)

SV_Position

在 Direct3D 9 中为 VPOS

SV_Position 为 float4 类型。

VPOS 为 float2 类型。

像素着色器输入

屏幕空间中的像素或示例位置

例如 - float4 pos : SV_Position

gl_FragDepth

该变量为 float 类型。

深度缓冲区数据

SV_Depth

在 Direct3D 9 中为 DEPTH

SV_Depth 为 float 类型。

像素着色器输出

深度缓冲区数据

 

使用语义指定位置、颜色等作为顶点着色器输入和像素着色器输入。必须将输入布局中的语义值与顶点着色器输入相匹配。例如,请参阅将 GLSL 变量移植到 HLSL 的示例。有关 HLSL 语义的详细信息,请参阅语义

将 GLSL 变量移植到 HLSL 的示例

下面我们介绍在 OpenGL/GLSL 代码中使用 GLSL 变量的示例,然后介绍在 Direct3D/HLSL 代码中的等效示例。

GLSL 中的 uniform、attribute 和 varying

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 应用代码

C++
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 asssembly 
// 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 呈现代码

C++
// 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);

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值