cesium比较区别 opengl_Cesium原理篇:Material

Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网站,我觉得他写的已经够好了。在开始普及概念前,推荐一首我此刻想到的歌《光---陈粒》。 在真实世界里,每个物体会对光产生不同的反应。钢看起来比陶瓷花瓶更闪闪发光,一个木头箱子不会像钢箱子一样对光产生很强的反射。每个物体对镜面高光也有不同的反应。有些物体不会散射(Scatter)很多光却会反射(Reflect)很多光,结果看起来就有一个较小的高光点(Highlight),有些物体散射了很多,它们就会产生一个半径更大的高光。如果我们想要在OpenGL中模拟多种类型的物体,我们必须为每个物体分别定义材质(Material)属性。

我们指定一个物体和一个光的颜色来定义物体的图像输出,并使之结合环境(Ambient)和镜面强度(Specular Intensity)元素。当描述物体的时候,我们可以使用3种光照元素:环境光照(Ambient Lighting)、漫反射光照(Diffuse Lighting)、镜面光照(Specular Lighting)定义一个材质颜色。通过为每个元素指定一个颜色,我们已经对物体的颜色输出有了精密的控制。现在把一个镜面高光元素添加到这三个颜色里,这是我们需要的所有材质属性:

structMaterial

{

vec3 ambient;

vec3 diffuse;

vec3 specular;floatshininess;

};

以上是对材质的一个最简单概括,我们下面进入Cesium的环节。先来看看Cesium在Shader中对Material的定义:

struct czm_material

{

vec3 diffuse;floatspecular;floatshininess;

vec3 normal;

vec3 emission;floatalpha;

};

和上面给出的结构体大致相同,区别是少了环境光ambient,但多了法向量normal,自发光emission和alpha,我们带着这个疑问看一下Cesium处理材质的片段着色器:

varying vec3 v_positionEC;

varying vec3 v_normalEC;voidmain()

{

vec3 positionToEyeEC= -v_positionEC;

vec3 normalEC=normalize(v_normalEC);

#ifdef FACE_FORWARD

normalEC= faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);

#endif

czm_materialInput materialInput;

materialInput.normalEC=normalEC;

materialInput.positionToEyeEC=positionToEyeEC;

czm_material material=czm_getDefaultMaterial(materialInput);

gl_FragColor=czm_phong(normalize(positionToEyeEC), material);

}

此时的坐标系是以相机为中心点,首先获取当前点的位置和法向量,通过czm_getMaterial获取默认的一个材质对象,gl_FragColor通过czm_phong方法得到对应的颜色。对于phong,在OpenGL SuperBible里面有详细的说明,大概就是通过material的属性,根据光的位置和光的颜色,最终计算出在该点当前环境和自身材质的影响下对应的颜色。我们来看看czm_phong的实现:

vec4 czm_phong(vec3 toEye, czm_material material)

{float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);if (czm_sceneMode ==czm_sceneMode3D) {

diffuse+= czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);

}float specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material) +czm_private_getSpecularOfMaterial(czm_moonDirectionEC, toEye, material);

vec3 materialDiffuse= material.diffuse * 0.5;

vec3 ambient=materialDiffuse;

vec3 color= ambient +material.emission;

color+= materialDiffuse *diffuse;

color+= material.specular *specular;returnvec4(color, material.alpha);

}

如上是phong颜色计算的算法,我并没有给出getLambertDiffuse和getSpecular的具体代码,都是光的基本物理规律。这里要说的是getLambertDiffuse的参数,如果是球面物体时,会调用czm_private_phong,此时参数为czm_sunDirectionEC,也就是太阳的位置,而这里认为光源的位置是靠近相机的某一个点,另外,环境光ambient默认是反射光的一半,这个也说的过去,最后我们看到最终颜色的alpha位是material.alpha。

上面是Shader中涉及到材质的一个

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值