您的位置:首页 > 其它

[osg]源码分析:osg::Material

2014-03-13 23:13 134 查看
[cpp] view
plaincopy

<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使用

[cpp] view
plaincopy

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还提供了一个更简单(当然功能不足)的函数:

[cpp] view
plaincopy

void glColorMaterial(GLenum face, GLenum mode);

可以将材料属性直接设置为当前的颜色(glColor)。

三、环境

对于环境光的反射,有如下两个函数:

[cpp] view
plaincopy

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)

+ 所有光源对一个顶点的贡献
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: