1.4怎么用HLSL着色器

本文介绍如何在Direct3D应用程序中使用HLSL着色器,包括编译着色器代码、创建顶点着色器、设置着色器变量及将其应用于渲染管线等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.4怎么用HLSL着色器

应用程序中对HLSL着色器的使用分为以下步骤:

1.       加载(称为编译更为妥当)着色器代码;

2.       创建(顶点/像素)着色器;

3.       对着色器中的变量进行赋值,完成应用程序和着色器之间的通信。

4.       把着色器设定到渲染管道中;

本例使用的着色器是一个顶点着色器,因此我们将通过顶点着色器的使用来讲解着色器的使用过程,像素着色器的使用过程与此大同小异,二者之间仅有些微差别。

 

1.4.1声明全局变量

IDirect3DVertexShader9* BasicShader = 0; //顶点着色器指针

 

ID3DXConstantTable* BasicConstTable = 0; //常量表指针

D3DXHANDLE WVPMatrixHandle          = 0;

D3DXHANDLE ColorHandle              = 0;

 

ID3DXMesh* Teapot                   = 0; //指向程序中D3D茶壶模型的指针

 

1.4.2编译着色器

通过D3DXCompileShaderFromFile函数从应用程序外部的文本文件BasicHLSL.txt中编译一个着色器:

//编译后的着色器代码将被放在一个buffer中,可以通过ID3DXBuffer接口对其进行访问,之后的着色器将从这里创建

       ID3DXBuffer* shaderBuffer      = 0;

       //用于接受错误信息

       ID3DXBuffer* errorBuffer       = 0;

 

       //编译着色器代码

       D3DXCompileShaderFromFile("BasicHLSL.txt", //着色器代码文件名

                                                   0,

                                                   0,

                                                   "SetColor", //入口函数名称

                                                   "vs_1_1", //顶点着色器版本号

                                                   D3DXSHADER_DEBUG,// Debug模式编译      

                                                   &shaderBuffer, //指向编译后的着色器代码的指针

                                                   &errorBuffer,

                                                   &BasicConstTable); //常量表指针

1.4.3创建着色器

       应用程序通过CreateVertexShader创建一个顶点着色器,注意使用了上一步得到的shaderBuffer

       g_pd3dDevice->CreateVertexShader((DWORD*)shaderBuffer->GetBufferPointer(), &BasicShader);

1.4.3对着色器中的变量进行赋值

1.3.4节说到着色器的全局变量在应用程序中赋值而在着色器程序中使用,这是应用程序和着色器通信的关键所在,这里就具体说明赋值过程。

着色器中的全局变量在编译后都被放在一个叫常量表的结构中,我们可以使用ID3DXConstantTable接口对其进行访问,参照1.4.1中编译着色器函数D3DXCompileShaderFromFile的最后一个参数,该参数即返回了指向常量表的指针。

对一个着色器中变量进行赋值的步骤如下:

1.       通过变量名称得到指向着色器变量的句柄;

还记得在BasicHLSL.x着色器文件中我们声明的两个全局变量吗:

        matrix WVPMatrix;

vector color;

              我们在应用程序中相应的声明两个句柄:

D3DXHANDLE WVPMatrixHandle          = 0;

D3DXHANDLE ColorHandle              = 0;

              然后通过变量名得到分别得到对应的两个句柄:

                     WVPMatrixHandle = BasicConstTable->GetConstantByName(0, "WVPMatrix");

                     ColorHandle = BasicConstTable->GetConstantByName(0, "color");

2.       通过句柄对着色器变量进行赋值;

我们可以先设置各变量为默认值:

        BasicConstTable->SetDefaults(g_pd3dDevice);

之后,可以使用ID3DXConstantTable::SetXXX函数对各个变量进行赋值:

HRESULT SetXXX(

  LPDIRECT3DDEVICE9 pDevice,

  D3DXHANDLE hConstant,

  XXX value

);

其中XXX代表变量类型,例如Matrix类型的变量就要使用SetMatrix函数赋值,而Vector类型的则要使用SetVector来赋值。

1.4.4把着色器设定到渲染管道中

       这里我们使用SetVertexShader方法把顶点着色器设定到渲染管道中:

              g_pd3dDevice->SetVertexShader(BasicShader);

1.4.5整个渲染过程如下

在渲染过程中,我们设定顶点的变换坐标和颜色值,渲染代码如下:

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,

D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

    //开始渲染

    g_pd3dDevice->BeginScene();

 

    //得到世界矩阵、观察矩阵和投影矩阵

    D3DXMATRIX matWorld, matView, matProj;

    g_pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);

    g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView);

    g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj);

 

    D3DXMATRIX matWVP = matWorld * matView * matProj;

    //通过句柄对着色器中的WVPMatrix变量进行赋值

    BasicConstTable->SetMatrix(g_pd3dDevice, WVPMatrixHandle, &matWVP);

   

    D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f);

    //通过句柄对着色器中的color变量进行赋值,这里我们赋值为黄色

    BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

 

    //把顶点着色器设定到渲染管道中

    g_pd3dDevice->SetVertexShader(BasicShader);

 

    //绘制模型子集

    Teapot->DrawSubset(0);

 

    //渲染完毕

    g_pd3dDevice->EndScene();

    g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

 

       编译运行程序,运行效果如图1.2所示,这里我们将顶点颜色设置为黄色,如果读者在渲染过程中不断变换对着色器变量color的赋值,你将会得到一个色彩不断变幻的D3D茶壶。

D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f); //读者可以尝试改变颜色值

BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

1.2 着色器效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值