DirectX 高级着色语言HLSL入门

为了编写着色器程序,我们需要一种高级着色器语言(High-Level Shading Language ,简称HLSL) 。 在DirectX 8中,着色器是用低级着色器汇编语言编写的。
DirectX 9支持一种高级着色器语言来写。
使用HLSL 编译器,我们可以编译我们的代码到任何可用shader版本,使用汇编语言我们将不得不为每个需要的版本移植代码。
HLSL 同C和C++语法很类似。

在记事本中编写着色器并保存成一般的ASCII文本文件,然后可以用D3DXCompileShaderFromFile函数来编译它们。

下面用HLSL编写的一个简单的顶点着色器,用记事本生成并保存成文本文件“VertexShader.cxx”。
顶点着色器用组合视图和投影矩阵转换顶点,并设置顶点漫射光为红色。

    matrix g_view_proj_matrix;
    const vector RED = {1.0f, 0.0f, 0.0f, 1.0f};
    
    struct sVertexInput
    {
        vector position : POSITION;
    };

    struct sVertexOutput
    {
        vector position : POSITION;
        vector diffuse  : COLOR;
    };

    sVertexOutput main(sVertexInput input)
    {
            sVertexOutput output = (sVertexOutput)0;    
            output.position = mul(input.position, g_view_proj_matrix);    
        output.diffuse = RED;    
        return output;
    }


首先是2个全局变量:

matrix g_view_proj_matrix;
const vector BLUE = {0.0f, 0.0f, 1.0f, 1.0f};

第1个变量g_view_proj_matrix是矩阵类型,它是一个在HLSL内创建的4×4的矩阵类型。这个变量保存视图与投影的组合矩阵,它描述两者的变换。使用这种方法我们只要做一个向量和矩阵的乘法(而不是二个)。在着色器源代码的任何地方都没有初始化这个变量,因为它是我们在应用程序的源代码里设置的,而不是在着色器中。从应用程序向着色器程序通讯是常用的操作。
第二个变量BLUE是built-in(内建)类型的4D向量,我们简单的将它初始化成蓝色,它是个RGBA的颜色向量。

输入和输出结构
在全局变量定义之后,定义2个特殊的结构,我们调用输入和输出结构。对于顶点着色器而言,这些结构定义了顶点的数据,分别是:

struct sVertexInput
{
  vector position : POSITION;
};

struct sVertexOutput
{
  vector position : POSITION;
  vector diffuse : COLOR;
};

注意:给像素着色器的结构定义输入和输出像素数据。
在例子中,INPUT 顶点着色器只包含位置成员(POSITION),OUTPUT顶点着色器包含位置和颜色成员(POSITION and COLOR)。

特殊的冒号是一种语义,用于是声明变量。这与vertex结构中的自由顶点格式(FVF)相似。
": COLOR"是说顶点的漫射光是用sVertexOutput结构的COLOR成员来说明的。
注意:从底层来说,着色器变量的语义和语法同硬件寄存器是相关联的。
即,input变量与input寄存器关联,output变量与output寄存器关联。例如,sVertexInput中的position成员与顶点input的position寄存器相关联。同样,diffuse与顶点的output的color寄存器关联。

函数的入口点
在C++程序中,每个HLSL程序有一个入口点。在我们的着色器例子中,我们调用入口点函数main。然而名字不是强制的。入口点函数名可以是任何有效的函数名,入口点函数必须有一个input结构参数,它通过input顶点进入着色器。入口点函数必须返回一个output结构实例,在着色器中使用output操作顶点。

sVertexOutput main(sVertexInput input)
{

 注意:实际上,使用input、output结构不是强制的。例如,有时你将会看到使用类似下面的语法,特别是在像素着色器中:

float4 Main(in float2 base : TEXCOORD0,
            in float2 spot : TEXCOORD1,
            in float2 text : TEXCOORD2) : COLOR
{
...

}


例子中,输入到着色器中的参数是3个纹理坐标。着色器输出(返回)一个颜色,COLOR语句在函数的声明以后。这种定义是类似于: 
 

struct INPUT
{
     float2 base : TEXCOORD0;
     float2 spot : TEXCOORD1;
     float2 text : TEXCOORD2;
};

struct OUTPUT
{
     float4 c : COLOR;
};
 
OUTPUT Main(INPUT input)
{
...

}


输入点函数负责根据给定的input顶点计算output顶点。例子中的着色器简单的变换input顶点到视图空间和投影空间,设置顶点颜色为红色,并返回结果顶点。首先我们定义sVertexOutput的实例并初始化所有成员为0。

sVertexOutput output = (sVertexOutput)0;
 

然后着色器变换input顶点位置用g_view_proj_matrix变量,使用mul函数。它是一个built-in(内建)函数,实现向量与矩阵相乘,或矩阵与矩阵相乘。我们保存结果变换的向量(在output实例的position成员中)。

output.position = mul(input.position, g_view_proj_matrix);


然后设置output的成员diffuse的颜色为红色:
output.diffuse = RED;

 
最后返回结果向量:
return output;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值