天天看点

HLSL shader编程中顶点着色器与像素着色器函数中的参数传递解析

HLSL基本以C语言的习惯来写的,但是如果完全以C语言的角度来看,我个人感觉入门最难理解就是顶点着色器和像素着色器的两个函数的参数传递了。

下面以最简单的HLSL中效果框架举例说下自己的理解。

uniform extern float4x4 gWVP;

struct OutputVS

{

float4 posH : POSITION0;

float4 color : COLOR0;

};

OutputVS ColorVS(float3 posL : POSITION0, float4 c : COLOR0)

{

// Zero out our output.

OutputVS outVS = (OutputVS)0;

// Transform to homogeneous clip space.

outVS.posH = mul(float4(posL, 1.0f), gWVP);

// Just pass the vertex color into the pixel shader.

outVS.color = c;

// Done–return the output.

return outVS;

}

float4 ColorPS(float4 c : COLOR0) : COLOR

{

return c;

}

technique ColorTech

{

pass P0

{

// Specify the vertex and pixel shader associated with this pass.

vertexShader = compile vs_2_0 ColorVS();

pixelShader = compile ps_2_0 ColorPS();

}

}

首先是定义的OutputVS,这里是作为顶点着色器的输出,先不用管。看顶点着色器函数里面的参数:

OutputVS ColorVS(float3 posL : POSITION0, float4 c : COLOR0)

{

}

相比C语言函数,最让初学者疑惑的是里面两个参数float3 posL : POSITION0, float4 c : COLOR0是哪里传进来的?其实这两个参数是固定的由Directx的pipeline传进来的。在Directx中我们都会定义我们的顶点格式以及为其注册,如下:

//============================================================

//先在Directx的相关初始化函数定义我们的顶点格式

struct VertexCol

{

VertexCol():pos(0.0f, 0.0f, 0.0f),col(0x00000000){}

VertexCol(float x, float y, float z, D3DCOLOR c):pos(x,y,z), col(c){}

VertexCol(const D3DXVECTOR3& v, D3DCOLOR c):pos(v),col(c){}

D3DXVECTOR3 pos;

D3DCOLOR col;

static IDirect3DVertexDeclaration9* Decl;

};

D3DVERTEXELEMENT9 VertexColElements[] =

{

{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},

{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},

D3DDECL_END()

};

HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl));

//=============================================================

//然后在调用IDirect3DDevice9::Draw**()之类函数之前告知Directx我们的顶点格式。

HR(gd3dDevice->SetVertexDeclaration(VertexCol::Decl));

//================================================================

这样我们在D3DVERTEXELEMENT9里面定义的顶点成分{……D3DDECLUSAGE_POSITION, 0}就会传递给顶点着色器参数中的float3 posL : POSITION0, 而和{……D3DDECLUSAGE_COLOR, 0}就传给顶点着色器参数中的float4 c : COLOR0。

顶点着色器计算好后得到每个像素的OutputVS,输出到像素着色器中。

//=============================

float4 ColorPS(float4 c : COLOR0) : COLOR

{

return c;

}

如上像素着色器的float4 c : COLOR0则来自于OutputVS中的float4 color : COLOR0;

像素着色器再输出计算得到的每个像素的颜色值,就是我们在屏幕看到的结果了。

继续阅读