麒麟子

~~

导航

<2010年4月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

统计

常用链接

留言簿(12)

随笔分类

随笔档案

Friends

WebSites

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜

游戏开发历程之材质系统

材质,这个词有各行各业都有自己的解释。

美工把物体贴图和物体颜色,高光等统称为材质。D3D和OPENGL这样的图形接口则把物体表面贴图单独叫做纹理,而把漫反射,高光等叫做材质。

 

而在游戏引擎或图形引擎中提到的材质,则与此不同。 引擎中提到的材质不仅上面的的内容。 引擎中所谓的材质,是指物体在渲染时一系列的状态控制。 如,ALPHA混合开关以及ALPHA混合因子、纹理过虑方式,纹理通道状态、纹理矩阵、裁剪模式等,在D3D中,就是SetRenderState,SetTextureStageState,SetSamplerStateState等所控制的。在OPENGL中,则大多数由glEnable所控制。

 

我们所提到的材质系统,则是以此为基础展开的。 上面提到的这些因子,组成了我们的材质。 也是我们在渲染一个物体的时候,提交到设备的状态控制值。 一个物体的一次渲染,我们称作一个PASS。于是我们顺其自然地将这个渲染时的材质控制的最小单位命名为Pass,则:

 

struct TextureState

{

    void* Texture;

    int ColorOp;

    int ColorAgr1;

    int ColorAgr2;

    int AlphaOp;

    int AlphaAgr1;

    int AlphaAgr2;

.....//更多内容

};

 

class CPass

{

   CColor mAmbient;

   CColor mDiffuse;

   ....更多内容

 

    bool mAlphaEnable;

    int mScrBlend;

    int mDstBlend;

    int mCullMode;

   TextureState[4] mTextureStates;

  ...更多内容

};

 

当我们渲染一个物体的时候,只需要将这个类里面的状态应用到设备,即可完成对物体的绘制。

 

材质系统的基本内容就是这些,这也是最容易做到的事情。

但是,我们都知道,像D3D或OPENGL这样的图形接口每设置一次GPU状态的时候,都会有一定的开销(通过查看相关文档可以看到某些函数的具体开销值)。而为了保证我们的渲染流畅,我们不得不减少这样的开销。

 

很自然地,我们会想到,尽量减少切换。而如何减少切换呢。我们可以记录下自己的硬件状态,在设置下一个的时候,先判断当前硬件状态是否相同,如果相同。则不用再设置。 虽然某些图形接口在其层底做了类似的功能。但我们外部判断一下,也未尝不可。从D3D上来讲,外部判断比让其内部判断效率更佳。需要注意的是,由于我们在自己的程序里做了相同判断。因此,当有另一个程序也修改设备状态的时候,就会产生意想不到的效果。所以,我们应该适当的查询一下设备状态,并更新自己的状态记录表。至于这个查询间隔,就要根据自己的实际情况来测试了。

 

 

通过记录状态的方法来提升的效率是很不明显的,因此,我们需要对材质进行排序,至于怎么排序,这算法上的问题,在此先不作过多解释。 总之,我们将相似的材质排在一起。由于材质很相似,绘完一个再绘下一个的时候,减少了切换,从而大大提升了效率。

 

既然已经是涉及到设备了,我们总得考虑一下设备问题。 如果设备不支持我们当前给定的材质状态,怎么办? 返回FALSE不渲染。还是让程序DOWN掉?  对于一些重要的性能,设备不支持让程序DOWN掉是最好的做法,但是,对于像纹理混合通道不足的情况,让其DOWN掉就显得划不来了。毕竟我们设计的游戏程序是想让更多的玩家能玩不是? 这样就会涉及到PASS的拆分问题。

 

对于PASS的拆分,OGRE已经做得很好了。根据用户的设备性能,如果不满足,就一直拆分,拆到用户满足为止,最后让一个物体渲染多次,来实现多个纹理通道混合的效果。 而多PASS则是在渲染的时候不得不考虑的地方,毕竟有些物殊效果非得用多PASS不可。

 

对于多PASS的设计,我们可以参考OGRE的材质方法或是D3DX的效果框架。我们把完成一个最终效果的方案称作一个渲染技术 Technique ,一个技术可由多个Pass来完成。

 

class Technique

{

...更多内容

 vector<CPass*> mPasses;

};

 

这样就满足了我们的需求。  对于同一种效果,我们可以提供多种Technique供程序选择。 而这个选择的条件则可以是根据硬件性能,或是玩家手动选择的配置来实现。

最后结构如下:

class CMaterial

{

public:

...更多内容

vector<CTechnique*> mRenderTechs

};

 

 

 

乱七八糟地说了一通,希望没晕死人!!!

posted on 2010-04-24 16:13 麒麟子 阅读(1551) 评论(2)  编辑 收藏 引用 所属分类: Game and Engine

评论

# re: 游戏开发历程之材质系统 2010-04-24 18:23 陈昱(CY)

期待下一篇,挂在材质上的人学习了  回复  更多评论   

# re: 游戏开发历程之材质系统 2010-04-24 18:33 小时候可靓了

@陈昱(CY)
Vczh在我还啥都不懂的时候,就已经很厉害了哇。。原来是你寝室的同学。幸会,幸会!  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理