DirectX9:高级篇 高级着色语言(HLSL)

一.简介

高级着色语言(High)可以编写顶点着色器和像素着色器,取代固定功能流水线中的部分功能,在图形卡的GPU(Graphics Processing Unit,图形处理单元)中执行

注意:如果图形卡不支持顶点着色器和像素着色器,可以切换为REF设备,但是这个设备会运行很慢

Shader language目前有3种主流语言:基于OpenGL的GLSL(OpenGL Shading Language)

                                                           基于Direct3D的HLSL(High Level Shading Language)

                                                            NVIDIA公司的Cg(C for Graphic)语言

在以前的显卡中,图像的呈现就像流水线一样,不能够进行编程.后来有了GPU,就可以通过编程来让GPU进行计算.

二.D3DXCompileShaderFromFile()

可以用.txt文本文件来存储着色器代码,再用D3DXCompileShaderFromFile()来加载

HRESULT D3DXCompileShaderFromFile(

  LPCSTR pSrcFile,

  CONST D3DXMACR0* pDefines,

  LPD3DXINCLUDE pInclude,

  LPCSTR pFunctionName,

  LPCSTR pTarget,

  DWORD Flags,

  LPD3DXBUFFER* ppShader,

  LPD3DXBUFFER* ppErrorMsgs,

  LPD3DXCONSTANTTABLE* ppConstantTable

);

// 调用D3DXCompileShaderFromFile

ID3DXConstantTable* TransformConstantTable = 0;
ID3DXBuffer* shader = 0;
ID3DXBuffer* errorBuffer = 0;

hr = D3DXCompileShaderFromFile(
         "transform.txt",  
         0, 
         0,
         "Main",
         "vs_2_0",
         D3DXSHADER_DEBUG,
         &shader,
         &errorBuffer,
         &TransformConstantTable);

if(errorBuffer)
{
  ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
  d3d::Release<ID3DXBuffer*>(errorBuffer);
}

if(FAILED(hr))
{
::Message(0, "D3DXCreateEffectFromFile()", 0, 0);
return false;
}

三.HLSL(高级着色器语言)语法

1.常量

每一个着色器都有一个常量表,它是用来存储着色器的变量.

在 D3DX 库中有 ID3DXConstantTable 接口来访问着色器的常量表,通过这个接口可以设置着色器源代码中的变量

(1) 获取常量句柄

D3DXHANDLE ID3DXConstantTable::GetConstantByName(

  D3DXHANDLE hConstant,

  LPCSTR pName        // 指向在着色器源代码中的变量

);

D3DXHANDLE h0;
h0 = ConstTable->GetConstantByName(0, "ViewProjMatrix");
(2) 设置常量
// 设置布尔值
bool b = true;
ConstTable->SetBool(Device, handle, b);

// 设置布尔数组
bool b[3] = {true, false, true};
ConstTable->SetBoolArray(Device, handle, b, 3);

// 设置浮点数
float f = 3.14f;
ConstTable->SetFloat(Device, handle, f);

// 设置浮点数组


// 设置整数
int x = 4;
ConstTable->SetInt(Device, handle, x);

// 设置整数数组
int x[4] = {1, 2, 3, 4};
ConstTable->SetIntArray(Device, handle, x, 4);

// 设置一个4*4的矩阵
D3DXMATRIX M(...);
ConstTable->SetMatrix(Device, handle, &M);

// 设置一个4*4的矩阵数组
D3DXMATRIX M[4];
ConstTable->SetMatrixArray(Device, handle, M, 4);

// 设置一个4*4的矩阵指针的数组
D3DXMATRIX* M[4];
ConstTable->SetMatrixPointerArray(Device, handle, M, 4);

// 设置一个4*4的矩阵的转置
D3DXMATRIX M(...)
D3DXMatrixTranspose(&M, &M);
ConstTable->SetMatrixTranspose(Device, handle, &M);

// 设置一个4*4的矩阵转置的数组
D3DXMATRIX M[4];
ConstTable->SetMatrixTransposeArray(Device, handle, M, 4);

// 设置一个4*4矩阵转置的指针的数组
D3DXMATRIX* M[4];
ConstTable->SetMatrixTransposePointerArray(Device, handle, M, 4);

// 设置一个 D3DXVECTOR4类型的变量
D3DXVECTOR4 v(1.0f, 2.0f, 3.0f ,4.0f);
ConstTable->SetVector(Device, handle, &v);

// 设置一个向量的数组
D3DXVECTOR4 v[3];
ConstTable->SetVectorArray(Device, handle, v, 3);

// 用来设置一个任意大小类型
D3DXMATRIX M(...)
ConstTable->SetValue(Device, handle, (void*)&M, sizeof(M));
(3) 设置常量默认值

HRESULT ID3DXConstantTable::SetDefaults(

  LPDIRECT3DDEVICE9 pDevice

);

2.全局变量

3.内置变量

bool--true/false,HLSL提供true和false关键字

int--32位有符号整数

half--16位浮点数

float--32位浮点数

double--64位浮点数

4.向量类型

vector是一个4D向量,每个分量都是float类型

vector<T,n>是一个n(1~4)维向量,每个分量都是T类型,

5.矩阵类型

matrix是一个4*4矩阵,每个分量都是float类型

matrix<T,m,n>是一个m*n(1~4)维向量,每个分量都是T类型

6.数组类型

float M[4][4];

half p[4];

vector v[12];

7.结构体类型

struct MyStruct
{
  matrix T;
  vector n;
  float f;
  int x;
  bool b;
};

MyStruct s;
s.f = 5.0f;

 

8.类型转换

// 强制类型转换

float f = 5.0f;
matrix m = (matrix)f;

9.关键字

asm      bool        compile    const             decl           do

double  else         extern      false               float           for

half       if              in             inline              inout          int

matrix    out          pass       pixelsshader   return         sampler

shared  static        string     struct               technique   texture

true       typedef     uniform    vector     vertexshader  void

volatile   while

  • typedef
// 将向量类型命名为点point

typedef const float CFLOAT;
typedef vector<float, 3> point;
Point myPoint;

10.操作符

 

11.自定义函数

12.内置函数

在DirectX文档中Content标签页下的 DirectX Graphics Reference Shader Reference High Level Shader Language Intrinsic Functions中就可以找到内置HLSL函数的完整列表

abs(x)          返回 |x|

ceil(x)          返回 >=x 的最小整数

clamp(x, a, b)        在[a, b]范围内选取(如果在范围内就返回x,如果不是就返回a或b)

cos(x)          返回 x 的余弦值,这里x是弧度值

cross(u, v)        返回 u 和 v 的叉乘结果

degrees(x)        将 x 从弧度转换为角度

determinant(M)      返回矩阵 M 的行列式det(M)

distance(u, v)       返回 u 点和 v 点之间的距离 |v - u|

dot(u , v)         返回 u 和 v的点乘结果

floor(x)          返回 <= x的最大整数

length(v)         返回 |v|

lerp(u, v, t)        在 u 和 v 之间线性插值,根据参数t(0 <= t <= 1)

log(x)           返回 ln(x)

log10(x)          返回 log10(x)

log2(x)          返回 log2(x)

max(x, y)         如果 x >= y,则返回x,否则返回y

min(x, y)         如果 x <= y,则返回x,否则返回y

mul(M, N)          返回矩阵乘积 MN

normalize(v)         返回 v/ |v| (单位化向量)

pow(b, n)         返回 b 的 n 次方

radians(x)          将 x 从角度转换为弧度

reflect(v, n)        给定向量 v 和表面法线 n,计算其反射向量

refract(v, n, eta)      给定向量 v 表面法线 n 和两种材质的两个折射索引的比率 eta,计算其反射向量

rsqrt(x)          返回 x 的平方根的倒数

saturate(x)         返回clamp(x, 0.0, 1.0)

sin(x)             返回 x 的正弦,其中 x 为弧度值

sincos(int x, out s,out c)    返回 x 的正弦和余弦,其中 x 为弧度值

sqrt(x)           返回 x 的平方根

tan(x)            返回 x 的正切,其中 x 为弧度值

transpose(M)        返回矩阵的转置M

float x = sin(1.0f);
float y = sqrt(4.0f);

vector u = {1.0f, 2.0f, -3,0f, 0.0f};
vector v = {3.0f, -1.0f, 0.0f, 2.0f};
float s = dot(u, v);

float3 i = {1.0f, 0.0f, 0.0f};
float3 j = {0.0f, 1.0f, 0.0f};
float3 k = cross(i, j);

matrix<float, 2, 2> M = {1.0f, 2.0f, 3.0f, 4.0f};
matrix<float, 2, 2> T = transpose(M);

四.HLSL(高级着色器语言)构成

1.输入输出结构

// 该顶点着色器对顶点实施了取景变换(view transformation)和投影变换(projection transform),并将顶点的漫反射颜色分量设为蓝色

// 一个HLSL内置的4*4矩阵类型,存储的是一个视图矩阵和投影矩阵的乘积
matrix ViewProjMatrix;

// 一个HLSL内置的4D向量类型,初始化为RGBA颜色的蓝色向量
vector Blue = {0.0f, 0.0f, 1.0f, 1.0f};

// 着色器输入结构的顶点数据
struct VS_INPUT
{
  // 位置分量
  vector position : POSITION;    
};

// 着色器输出结构的顶点数据
struct VS_OUTPUT
{
 // 位置分量 颜色分量
  vector position : POSITION;
  vector diffuse : COLOR;
};
// 另一种入口 函数的表示方法

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

struct OUTPUT
{
  float4 c : COLOR;
};

2.入口函数

// 主入口函数,输入顶点数据,返回输出顶点数据
VS_OUTPUT Main(VS_INPUT input)
{
  // 所有成员的值设为0
  VS_OUTPUT output = (VS_OUTPUT)0;

  // 矩阵相乘
  output.position = mul(input.position, ViewProjMatrix);

 // 漫反射分量
  output.diffuse = Blue;
  return output;
}
float4 Main(int float2 base : TEXCOORD0,
                 int float2 spot : TEXCOORD1,
                 int float2 text : TEXCOORD2) : COLOR
{
  ..
}
原文地址:https://www.cnblogs.com/k5bg/p/11075927.html