- <span style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif;">此类是关于材料属性的设置。</span>
一、从OpenGL的角度来看,材料有如下几种属性:
1. 环境;
2. 散射;
3. 镜面颜色;
4. 光泽度;
5. 发射光颜色。
也就是说,材料的属性必须与光照结合,才可能体现出作用。比如,给某材料设置了(1.0, 0.0, 0.0, 1.0),在没有光照的情况下,他仍是没有颜色的(或者颜色不定)。因而既然osg::Material封装了关于材料属性的部分,那么必定提供这5个方面的支持。
二、先来看看OpenGL设置材料属性的流程
OpenGL使用
- void glMaterial(GLenum face, GLenum pname, TYPE param)
来设置材料属性,材料属性的设置位于添加顶点数组之前。param是一个四元组(颜色)。
face表示对于哪一个面操作,可以是FRONT, BACK, FRONT_AND_BACK。
pname表示对哪一种属性操作,可以是GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS, GL_EMMISON, GL_COLOR_INDEXES。
OpenGL还提供了一个更简单(当然功能不足)的函数:
- void glColorMaterial(GLenum face, GLenum mode);
可以将材料属性直接设置为当前的颜色(glColor)。
三、环境
对于环境光的反射,有如下两个函数:
- void Material::setAmbient(Face face, const Vec4& ambient )
- const Vec4& Material::getAmbient(Face face) const
并用两个成员变量记录正面和反面相应的值:_diffuseFront和_diffuseBack。
五、镜面颜色
void Material::setSpecular(Face face, const Vec4& specular ) const Vec4& Material::getSpecular(Face face) const
并用两个成员变量记录正面和反面相应的值:_specularFront和_specularBack。
六、光泽度
void Material::setShininess(Face face, float shininess ) float Material::getShininess(Face face) const
并用两个成员变量记录正面和反面的相应的值:_shininessFront和_shininessBack。
七、发光颜色
void Material::setEmission(Face face, const Vec4& emission ) const Vec4& Material::getEmission(Face face) const
并用两个成员变量记录正面和反面的相应的值:_emissionFront和_emissionBack。
八、另外有两个函数
void Material::setTransparency(Face face,float transparency) void Material::setAlpha(Face face,float alpha)
看此函数的源码可以知道,这两个函数都是对四种(环境,散射,镜面,发射)材料属性的四元组的第四个分量设置的,alpha就是设置不透明度;而transparency就是设置透明度(即不透明度是1-transparency)。
九、最后所有的OpenGL语句都是在apply函数中调用的。
十、设置了上面的值后,而我们最终看到的颜色是由光射属性,材料属性,光照和点的位置以及点的法向所共同决定的,中间是复杂的数学过程,下面简单介绍。
1. 材料的发射光
直接就是Emission(material)。
2.经过缩放的全局环境光
由glLightMode(GL_LIGHT_MODEL_AMBIENT, type)指定的全局环境光(背景光)和由glMaterial指定的材料属性相乘:
ambient(light model) * ambient(material)
将RGB分别相乘。
3.每个光源的环境光成分
ambient(light) * ambient(material)
4. 每个光源的散射光成分
(max{L*n, 0}) * Diffuse(light) * Diffuse(material)
L=(Lx, Ly, Lz),为从顶点到光源位置的单位向量。
n=(nx, ny, nz),是顶点的单位法线向量。
5. 镜面光成分
(max{s*n, 0})^shininess * Specular(light) * Specular(material)
如果L*n=0,则镜面光成分为0。
6. 所有光源对一个顶点的贡献
每个淘汰的贡献=衰减因子*聚光灯效果*(环境光成分+散射光成分+镜面成分)
7. 最终顶点的颜色是综合了上面六个成分的颜色:
顶点颜色=Emission(material)
+ Ambient(light model) * Ambient(material)
+ 所有光源对一个顶点的贡献