(版本:TGEA1.0.3)

1. 基本概念

参见<TGEA中材质的使用>


2. 核心类



2.1. MaterialPropertyMap

MaterialPropertyMap是一个单件,存储了所有Material与纹理的映射信息。具体参Material与MaterialPropertyMap类说明。以下详细分析下MaterialPropertyMap

TGEA渲染部分源代码分析--Materials模块

图3-2 MaterialPropertyMap UML图

数据成员:

Vector<MapEntry> mMapEntries; 

这个向量中的每个元素都维护了一个材质对象的映射信息。

MapEntry的功能参MapEntry类的说明。

StringTableEntry name

为模型文件中存储的纹理信息,材质即是要和这个纹理对应。称之为纹理名(texture tag)。

materialName

存储的为脚本中的Material对象名。

成员函数:

bool addMapping(S32,char**)

创建一个新的MapEntry,并赋值。

2.2. MapEntry

MapEntry的UML如下:

TGEA渲染部分源代码分析--Materials模块

图3-3 MapEntry UML图

StringTableEntry name

为模型文件中存储的纹理信息,材质即是要和这个纹理对应。称之为texture tag。

materialName

存储的为脚本中的Material对象名。

2.3. MaterialList

MaterialList维护了一个模型上所带的所有材质,UML图如下:

TGEA渲染部分源代码分析--Materials模块 

图3-4 MaterialList UML图

数据成员:

Vector<MatInstance *> mMatInstList 

存储这个模型的所有的MatInstance, MatInstance才是真正的存储材质的对象。Material只是对它的一个包装。存储的为材质名。

VectorPtr<char *> mMaterialNames 

存储这个模型的所有texture tag,即纹理名。

这两个向量的元素是一一对应的,即存储了脚本中的材质对象与模型的纹理的映射信息。

成员函数:

void mapMaterials() 

进行材质与纹理的映射。

2.4. MatInstance 

TGEA渲染部分源代码分析--Materials模块

图3-5 MatInstance 

成员函数:

void processMaterial() 

处理材质关于渲染的各种属性。重要语句如下: 

mMaxStages = getNumStages();   

for( U32 i=0; i<mMaxStages; i++ )

{

GFXShaderFeatureData fd;

determineFeatures( i, fd );

if( fd.codify() )

{

      createPasses( fd, i );

}

}

关于stage,stage在TGEA中的概念类似于DirectX中的“pass”,即多道渲染。对同一个面片使用多个不同的shader进行渲染,最终将多次渲染的结果合成。

在材质脚本中已经指定了各道stage的渲染属性。在processMaterial中对针对每道stage生成相应的shader。

void determineFeatures( U32 stageNum, GFXShaderFeatureData &fd )

根据stage的标号来决定这道stage的shaderFeature。以下详细解释:

例如有材质的对象定义:

new Material(SphereGlow)

{

   mapTo = sphere_metal;

   baseTex[0] = "~/data/shapes/test/blobtex1";

   emissive[0] = true;

   glow[0] = true;

};

可以看到,下标为0的指定了0道stage的渲染特性。这些特性指定了最终的渲染效果。在引擎中这样的每个特性称为shader feature,这些特性是存储在Material类中。

可以看到determineFeatures()只接受了stage的标号。却没有任何的feature信息。他是如何创建这道stage相应的shaderfeature呢。

关键在于GFXShaderFeatureData结构中的一个枚举量:

enum

   {

      RTLighting = 0,   // realtime lighting

      TexAnim,

      BaseTex,

  DynamicLight,

  DynamicLightDual,

  DynamicLightMask,

  DynamicLightAttenuateBackFace,

  SelfIllumination,

      LightMap,

      LightNormMap,

      BumpMap,

      DetailMap,

  ExposureX2,

  ExposureX4,

      EnvMap,

      CubeMap,

      // BumpCubeMap,

      // Refraction,

      PixSpecular,

      VertSpecular,

      Fog,              // keep fog last feature

      NumFeatures,

   };

可见在此枚举上shader feature是按顺序排列的。共19个。

determineFeatures()函数中,有如下循环:

for( U32 i=0; i<GFXShaderFeatureData::NumFeatures; i++ ){

。。。。。。

}

在这里就依次判断材质中否具有这19个shader feature。最近再将具有的feature存入fd中。

void createPasses( GFXShaderFeatureData &fd, U32 stageNum )

根据传入shaderfeature fd,调用addPass来创建shader。

关于这个函数应该注意的是:creatrePasses()函数会根据shaderFeature的数目来决定创建shader的数目。因为受硬件性能所显,每个shader能执行的语句及使用的硬件寄存器(主要是纹理寄存器)有限,因此一个fd所包含的feature有时需要多个shader才能完成。TGEA记录每个feature要使用的寄存器数量,当fd中的feature使用的寄在器数量超过Shader Model支持的数量后,就会开始创建shader。而后继续处理fd中别的feature。

void addPass( RenderPassData &rpd, U32 &texIndex, GFXShaderFeatureData &fd,U32 stageNum )

调用GFX开始创建shader。GFX为TGEA的抽象图形层,封装了底层图形API,具体见第4章,第7章。

3. 流程 

     Materials模块的功能主要有:第一,完成材质与模型的对应.这样引擎才知道渲染模型时使用相应的材质;第二,利用脚本中材质对象的定义生成相应的shader。以下按照流程来分析,流程为两个部分组成:

1 Material::onAdd()起,功能为将材质映射信息存入MaterialPropertyMap

2 TSStatic::onAdd()起,从MaterialPropertyMap中读出映射信息,完成材质与模型的映射。并调用ShaderGen模块来生成shader。

3.1. Material::onAdd()开始

当引擎载入脚本代码执行时,对脚本对象会调用引擎中相应对象的onAdd函数,Material对象引起的流程如下:

在materials/material.cpp中:

Material::onAdd()

àMaterial::mapMaterial()

àMaterialPropertyMap::addMapping()

这段代码的作用是将材质与模型的映射信息存入MaterialPropertyMap

3.2. TSStatic::onAdd()开始  

当引擎载入脚本代码执行时,对脚本对象会调用引擎中相应对象的onAdd函数,对象引起的流程如下:

在game/ tsStatic.cpp中:

TSStatic::onAdd()

àmshape=ResouceManager->load(mshapeName)

àmshapeInstance= new TSShapeInstance()

àTSShapeInstance::buildInstanceData()

à TSShapeInstance:: setMaterialList(mShape->materialList)

à mMaterialList->mapMaterials()

à TSShapeInstance::initMatInstance()

àMatInstance::init()

àMatInstance::ProcessMaterial()

具体如下:

前三句为加载模型。具体见模型系统。

TSShapeInstance::setMaterialList(mShape->materialList):使用mShape的材质列表(实质上是texture tag),因为一个模型会带很多的纹理,每张纹理都要对应一个材质,所以实际上一个模型要对应许多材质.因此需要用一个列表来存储所有的材质信息.给TSShapeInstance的mMaterialList赋值。

mMaterialList->mapMaterials():从Map中读出映射信息并赋值,完成材质映射信息的填充。

TSShapeInstance::initMatInstance():初始化材质列表。

MatInstance::init():对材质列表中每个材质进行被始化。

MatInstance::ProcessMaterial():处理材质的各种属性,并根据这些属性调用ShaderGen创建shader。


相关文章:

  • 2021-12-30
  • 2021-11-27
  • 2022-12-23
  • 2022-12-23
  • 2021-11-22
  • 2021-11-09
猜你喜欢
  • 2021-11-07
  • 2021-12-05
  • 2021-06-08
  • 2022-12-23
  • 2021-11-23
  • 2021-10-04
  • 2021-08-19
相关资源
相似解决方案