Shader中的场景信息,也就是那些被写入常量表的全局数据,是与应用程序的相关数据绑定的。它们包含渲染一个shader所需要的各种渲染状态,就好象是在应用程序和shader之间的一份契约。Shader知道,它必须依靠应用通过特定变量来提供确定的数据,才能完成它的任务。没有这种场景数据,shader不能凭空操作,甚至连最简单的操作也不能执行。注意这种数据是单向的,只能从应用到shader中去,而且每当场景数据变化一次,在shader中的数据也必须随之更新。
这也就是说,shader是基于应用程序中的场景数据进行工作的,可以在引擎中定义好场景数据区,在每一次游戏循环的渲染前都提交一次场景数据,让shader正常工作。
如果在一个pass中渲染含多个纹理的物体,纹理的数据可能要在pass中进行修改,但是此时可能会发现,结果依然是只能画出一个纹理,这时候就需要用ID3DXEffect::CommitChange()方法。因为如果shader的状态在pass期间由于ID3DXEffect::Setx方法而改变,程序就必须通过这个方法来通知设备有状态的改变,而在pass之外,则不需要这个调用。因此在pass期间最好都写上这个方法,并把在pass期间的改变都写在这个方法前面,C++中示例如下:
//使用效果渲染网格
UINT numPasses;
this->m_pEffect->Begin( &numPasses, D3DXFX_DONOTSAVESTATE );
for( UINT iPass = 0; iPass < numPasses; iPass++ )
{
this->m_pEffect->BeginPass( iPass );
///设置纹理
m_pEffect->SetTexture( "Tex2D", pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
m_pEffect->CommitChanges();
pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
this->m_pEffect->EndPass();
}
this->m_pEffect->End();