这里我用DirectX9实现一遍逐片段光照与阴影贴图,阴影贴图的算法与OpenGL的相同,各位仔细看好了.
首先声明四个着色器并获取它们的常量句柄:
void initShaders() {
storeVertexShader=new Shader("../shader/store_vs.fx",SHADER_TYPE_VS);
modelMatrixStoreHand=storeVertexShader->constTable->GetConstantByName(NULL,"modelMatrix");
viewMatrixStoreHand=storeVertexShader->constTable->GetConstantByName(NULL,"viewMatrix");
projMatrixStoreHand=storeVertexShader->constTable->GetConstantByName(NULL,"projMatrix");
storePixShader=new Shader("../shader/store_ps.fx",SHADER_TYPE_PS);
texVertexShader=new Shader("../shader/tex_vs.fx",SHADER_TYPE_VS);
modelMatrixHand=texVertexShader->constTable->GetConstantByName(NULL,"modelMatrix");
viewMatrixHand=texVertexShader->constTable->GetConstantByName(NULL,"viewMatrix");
projMatrixHand=texVertexShader->constTable->GetConstantByName(NULL,"projMatrix");
normalMatrixHand=texVertexShader->constTable->GetConstantByName(NULL,"normalMatrix");
shadowMatrixHand=texVertexShader->constTable->GetConstantByName(NULL,"shadowMatrix");
texPixShader=new Shader("../shader/tex_ps.fx",SHADER_TYPE_PS);
ambHand=texPixShader->constTable->GetConstantByName(NULL,"amb");
diffHand=texPixShader->constTable->GetConstantByName(NULL,"diff");
lightDirHand=texPixShader->constTable->GetConstantByName(NULL,"lightDir");
ambMtlHand=texPixShader->constTable->GetConstantByName(NULL,"ambMtl");
diffMtlHand=texPixShader->constTable->GetConstantByName(NULL,"diffMtl");
}
store开头的顶点与片段着色器在渲染阴影贴图时使用,用于保存以光源位置为视点的场景深度,接着是取得mvp变换矩阵的句柄.
tex开头的顶点与片段着色器在渲染场景时使用,用于执行深度比较以及光照运算,然后也是获得mvp变换矩阵,法线变换矩阵,光源视点投影变换矩阵和各种光照参数的句柄.
有了这些句柄我们就可以给着色器中的常量传值了.
接着设置光照参数:
float lightd[4] = {1.0f, 1.0f, -1.0f, 0.0f};
float ambientLight[4] = {0.7f, 0.7f, 0.7f, 1.0f};
float diffuseLight[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float ambientLightMtl[4] = {0.7f, 0.7f, 0.7f, 1.0f};
float diffuseLightMtl[4] = {1.0f, 1.0f, 1.0f, 1.0f};
void initLight() {
D3DXVECTOR4 amb(ambientLight);
D3DXVECTOR4 diff(diffuseLight);
D3DXVECTOR4 lightDir(lightd);
D3DXVECTOR4 ambMtl(ambientLightMtl);
D3DXVECTOR4 diffMtl(diffuseLightMtl);
texPixShader->constTable->SetVector(d3d,ambHand,&amb);
texPixShader->constTable->SetVector(d3d,diffHand,&diff