天天看點

DirectX9:進階篇 進階着色語言(HLSL)一.簡介二.D3DXCompileShaderFromFile()三.HLSL(進階着色器語言)文法四.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