Cesium.Entity图片纹理在不同观察角度有不同亮度
测试代码:
viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(-92.0, 30.0, -76.0, 40.0),
material: "../images/rect.png",
}
});
测试图片:
rect.png
这个图片可以比较明显的观察到亮度的变化!
如果亮度变化不明显,可以监测rgb的值,也会发现有所不同
测试结果:
entity rectangle使用了图片纹理,在改变查看角度后
图片的亮度发生变化
分析过程1:
光的反射分为镜面反射和漫反射两类
镜面反射导致的??
镜面反射会受到“观察角度”与“光源角度”的影响
在cesium中,调整太阳角度,观察角保持不变,并没有出现纹理亮度的变化
所以排除了纹理使用镜面反射的原因。
漫反射导致的??
在光源(太阳)和物体相对位置和角度保持不变的时候
只改变观察者的位置
是不应该出现亮度变化的
所以也排除了漫反射。
分析过程2:源码跟踪
发现是因为shader中,在眼睛坐标系下给了2个固定的光源
vec4 czm_phong(vec3 toEye, czm_material material, vec3 lightDirectionEC)
{
// Diffuse from directional light sources at eye (for top-down)
float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);//固定光源1
if (czm_sceneMode == czm_sceneMode3D) {
// (and horizon views in 3D)
diffuse += czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);//固定光源2
}
float specular = czm_private_getSpecularOfMaterial(lightDirectionEC, toEye, material);
// Temporary workaround for adding ambient.
vec3 materialDiffuse = material.diffuse * 0.5;
vec3 ambient = materialDiffuse;
vec3 color = ambient + material.emission;
color += materialDiffuse * diffuse * czm_lightColor;
color += material.specular * specular * czm_lightColor;
return vec4(color, material.alpha);
}
思考:
关于这2个固定光源:
这2个固定光源,可以让人在任何角度,都可以看到明亮的entity
如果没有这2个光源,大家就要调整合适的太阳角度去照亮特定的entity
至于为啥要加这2个固定光源的更多原因,欢迎大家留言。
关于环境光:
为啥cesium不引入环境光这个参数信息?
解决方案:
Entity.rectangle.material="图片地址"
上述代码最后会使用ImageMaterialProperty类
模仿ImageMaterialProperty类写一个自定义的MaterialProperty
在下述shader中,把diffuse改成emission就可以了
Material.ImageType = "Image";
Material._materialCache.addMaterial(Material.ImageType, {
fabric: {
type: Material.ImageType,
uniforms: {
image: Material.DefaultImageId,
repeat: new Cartesian2(1.0, 1.0),
color: new Color(1.0, 1.0, 1.0, 1.0),
},
components: {
//下述diffuse改成了emission就可以了
diffuse:
"texture2D(image, fract(repeat * materialInput.st)).rgb * color.rgb",
alpha: "texture2D(image, fract(repeat * materialInput.st)).a * color.a",
},
},
translucent: function (material) {
return material.uniforms.color.alpha < 1.0;
},
});
上述代码引的是ImageMaterialProperty类使用的shader
自定义shader的时候,记着修改相关变量,比如Material.ImageType的值
(关于自定义MaterialProperty,请查询相关资料,在此不深入来说)