Ogre 光,材质与材质脚本

Mage小组 著
Email: norman_chen@163.com 
renwind@163.com
QQ: 18725262
http://www.173d8.com
http://blog.csdn.net/pizi0475

 


材质与材质脚本
基本概念
Ogre的材质(Material)
    为了优化渲染,必须把渲染状态的变化减少到最小。而最频繁的渲染状态改变是材料的变化(大多是纹理的变化)。
Ogre的Material类封装了物体的所有材料属性,类似于3D Studio中material的概念。平时不被认为是属于材料的属性,像culling模式和深度缓存设置等,也被Material包含近来了。因为这些属性同样影响了物体的外观,把它们放到Material类里可以集中设置所有影响物体的属性。这和D3D中只保存颜色组件而没有纹理映射的Material有明显不同。Ogre的Material可以被认为是’Shader’的等同物。
Material类包括如下几类属性:
1、 基本的表面材质属性,如对不同颜色的反射率、Shininess等等:
2、 组成Material的纹理层
3、 纹理之间的混合(Blend)方式
4、 深度缓冲设置
5、 Culling模式 
6、 纹理过滤方式(三线性过滤、双线性过滤)
7、 是否受光照影响
8、 Shading选项
9、 雾化
 其中第二条的纹理层可以有多个,Ogre在Material类的内部定义了TextureLayer类。
纹理层(TextureLayer)
 一个纹理层可以是一幅静止的图像,也可以是一幅以某种方式运动的图像,还可以是由多幅图像组成的动画。它可以实现多种纹理特效,如BUMPMAP、环境帖图、运动的纹理。
材质管理器(MaterialManager)
MaterialManager类负责管理Material库。和材质相关的类图如下:
 
 MaterialManager还负责分析Material脚本(Material Script),从而初始化Material的属性。下面我们来分析一下Ogre提供的材质脚本语言。
Ogre的材质脚本
Ogre提供的材质脚本可以帮助开发者简单的设置又酷又眩的材质特效,而不用重新编译。当然你也可以用Material和TextureLayer类提供的诸多成员函数来做到,但这就有点不太实用了。
Ogre材质脚本的默认扩展名为.material,你也可以通过 MaterialManager类的parseAllSources方法来规定新的扩展名。系统初始化时会自动分析所有的材质脚本文件,并设置材质的属性。注意,这里只设置材质的属性,并不会将材质的纹理调入内存,因为那样会招致极大的内存消耗!
示例一:环境帖图
 在场景中显示一个OGRE头,并设置其表面材质为环境帖图,该环境帖图的属性在Example.material中设置。我们先看一下createScene()函数的代码:
    void createScene(void)
    {
        //设置环境光
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

  //创建一个实体(OGRE头)
        Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh");

        //设置实体的材质
        ent->setMaterialName("Examples/EnvMappedRustySteel");

        // 将实体附属到场景根结点上
        mSceneMgr->getRootSceneNode()->createChild()->attachObject(ent);
}
 在这里,Entity的成员函数setMaterialName是关键,字符串类型的参数对应材质脚本中的材质名。"Examples/EnvMappedRustySteel"就是材质名,它在Example.material文件中定义了环境帖图,脚本代码如下:
 //材质名
Examples/EnvMappedRustySteel
{
 //环境光
  ambient 1.0, 1.0, 1.0
  //散射光
  diffuse 1.0, 1.0, 1.0
 shading phong
  //纹理层0
 {
  //纹理图象文件
   texture RustySteel.jpg
 }
  //纹理层1
 {
  //纹理图象文件
   texture spheremap.png
   //纹理层之间的颜色累加
   colour_op add
   //指定环境帖图的方式
  env_map spherical
  }
}
从这个例子中我们可以发现使用脚本来定义材质非常方便。首先,脚本采用类C++的语法,以{}作为分隔符,以//作为注释符。每一个Material必须有一个名字,在这个例子中就是Examples/EnvMappedRustySteel,它对应一个材质。脚本规定一个命令占一行,不可以串行。
Ogre为其材质脚本定义了许多关键字(命令),用来设置材质属性。如上例中的“ambient”与“diffuse”就是关健字,分别设置材质对环境光和散射光的反射率。在Material定义中嵌套一个“{}”,就代表一个纹理层,你可以在大括号中定义纹理层的属性,上例中有两层纹理,下层简单的显示了一幅名为“RustySteel.jpg”的图像 ,上层纹理采用了环境帖图并设定了两层纹理的混合方式为颜色相加。
材质脚本的关健字有很多,具体请参考Ogre Tutorials的“Material Script”一节。
示例二:Example.material
 分析并尝试更改Ogre运行环境中的Example.material文件,并在Ogre提供的演示TextureFx.exe中观察效果。下面列出的是TextureFx.exe中用到的三个材质的定义:
// 流动的水的特效
Examples/TextureEffect3
{
 ambient 0.2 0.2 0.2

 // 关闭硬件拣选与软件拣选,即双面渲染
 // 硬件拣选,由硬件渲染器负责。基于画三角形的方式(顺时针,逆时针)。<clockwise|anitclockwise|none> 
 // 软件拣选,在前几个信息改善到硬件器之前,进行拣选。基于三角形的前和后(由三角形的向量决定)。
 cull_hardware none
 cull_software none
 
 // 水用了两层纹理
 // 纹理层0
 {
  texture Water01.jpg
  scroll_anim -0.25 0.1
 }
 // 纹理层1
 {
  texture Water01.jpg
  scroll_anim -0.1 0.25
  // 纹理层1与纹理层2之间的混合方式,add代表两层颜色相加。
  colour_op add
 }
}

// 大小正弦波影响的特效
Examples/TextureEffect1
{
 ambient 0.75 0.75 0.75

 // 关闭硬件拣选与软件拣选,即双面渲染
 // 硬件拣选,由硬件渲染器负责。基于画三角形的方式(顺时针,逆时针)。 
 // 软件拣选,在前几何信息改善到硬件器之前,进行拣选。基于三角形的前和后(由三角形的向量决定)。
 cull_hardware none
 cull_software none

 // 纹理层0
 {
  // 纹理图的文件名
  texture BumpyMetal.jpg

  // wave_xform指定一个波形函数,来对指定的纹理层属性(scale或scroll或rotate)产生影响
  // wave_xform <纹理层的某个属性> <波形> <base> <频率> <相位> <振幅>
  // 下面这句可以解释成:纹理的宽度值 = 纹理的宽度值 * 正弦波当前时间的值(base+sine)
  wave_xform scale_x sine 0 0.1 0 5

  // 旋转速率 = 旋转速率 + 正弦波当前的值
  // wave_xform rotate sine 0.1 0.1 0 5    
 }
}


// 纹理流动的管道
Examples/TextureEffect2
{
 scene_blend add
 {
  texture Water02.jpg
  scroll_anim 0.5 0
 }
}

材质脚本关健字说明
ambient设置材质的环境光反射属性
格式: ambient <red> <green> <blue>
正确的参数在0.0和1.0之间取值。直接影响物体材质对环境光反射能力。默认值为白色(1.0 1.0 1.0)。
diffuse设置材质的漫反射属性
格式: diffuse <red> <green> <blue>
正确的参数在0.0和1.0之间取值。直接影响物体材质对漫射光的反射属性。默认值为白色(1.0 1.0 1.0)。
specular设置材质的镜面反射属性
格式: specular <red> <green> <blue> <shininess>
正确的颜色参数在0.0和1.0之间取值,shininess属性可以是任何正数。直接影响物体材质的镜面反射属性。默认值为无镜面反射(0.0 0.0 0.0 0.0)。
emissive设置材质本身的发光程度
格式: emissive <red> <green> <blue>
正确的颜色参数在0.0和1.0之间取值。 如果一个物体自发光,它将不需要外界的照明,但是,值得注意的是这不表明这个物体将会成为一个光源:它只会照亮自己。默认是黑色(0.0 0.0 0.0)。
scene_blend 设置与场景的混合方式,有两种形式
格式1: scene_blend <add|modulate|alpha_blend>
这个格式比较简单常用一些,参数意义如下:

 

add

渲染的结果将被以相加的方式加入场景之中,与scene_blend one one等价。对爆炸,火焰,光照,幽灵等效果比较好。

Modulate

渲染的结果与场景相乘。对烟、玻璃杯和单个的透明物效果较好。与scene_blend src_colour one_minus_src_colour等价。

alpha_blend

渲染结果中的Alpha成员将被用作遮罩。与scene_blend src_alpha one_minus_src_alpha等价。

格式2: scene_blend <src_factor> <dest_factor>
这个格式比较麻烦,但是比较完善。结果的计算公式为(texture * sourceFactor) + (scene_pixel * destFactor)其中sourceFactor destFactor如下:

One

常数1.0

Zero

常数0.0

dest_colour

当前点的颜色

src_colour

纹理对应点的颜色

one_minus_dest_colour

1 - (dest_colour)

one_minus_src_colour

1 - (src_colour)

dest_alpha

当前点的Alpha

src_alpha

纹理对应点的Alpha

one_minus_dest_alpha

1 - (dest_alpha)

one_minus_src_alpha

1 - (src_alpha)

默认值: scene_blend one zero (不透明)

depth_check是否开深度测试

格式: depth_check <on|off>
默认打开深度缓存。有助于判断两个点的遮挡关系和前后关系,体现三维立体感。

depth_write是否允许对已经存在的深度缓存进行写操作

格式: depth_write <on|off>

默认允许,关掉的话,则被关的Material会一直浮动在所有物体前面。

depth_func当深度缓存打开的时候,挑选一个比较函数

格式: depth_func <func>

always_fail

从不比较

always_pass

总是用新的换掉旧的

less

新的比旧的小就换掉

Less_equal

新的小于等于旧的就换掉

equal

等于就换掉

not_equal

不等于就换掉

greater_equal

新的大于等于旧的就换掉

greater

新的比旧的大就换掉

默认为:小于等于就换掉 depth_func less_equal

cull_hardware设置硬件Cull模式

格式: cull_hardware <clockwise|anitclockwise|none>

默认顺时针Cull。这与OpenGL的默认是一样的,但和D3D的默认相反。(因为Ogre用的是OpenGL采用的右手坐标系)

cull_software设置软件Cull模式

格式: cull_software <back|front|none>

默认背面。相当于硬件Cull模式的顺时针。

lighting光照

设置动态光照是否为此材质打开。如果关掉,将使材质本身的所有的ambient, diffuse, specular, emissiveshading属性无效,仅仅与外界的光照有关。

格式: lighting <on|off>

默认: lighting on

shading阴影模式

格式: shading <flat|gouraud|phong>

Flat

每个表面仅仅用一个颜色填充

gouraud

线性过渡表面颜色

phong

并非所有的硬件都支持,这种模式测定每一个顶点的颜色。

默认: shading gouraud

 


filtering设置纹理过滤方式


格式: filtering <none|bilinear|trilinear>
默认是双线性(bilinear)
Texture Layer专用属性
texture设置纹理要使用的图名
格式: texture <texturename>
无默认值,必须指定一个纹理名。
anim_texture动画纹理
设置动画纹理使用的图片文件名。
格式1 (短的): anim_texture <base_name> <num_frames> <duration>
指定一个图片名称,以这个名称后缀_1、_2一直到_num(由num_frames指定),duration指定间隔时间。
格式2 (长的): anim_texture <frame1> <frame2> ... <duration>
一个一个指定图片名称,duration指定间隔时间。
无默认值

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值