3D Tiles 白模糊成一片白,看不出轮廓
模型加载成功了,相机也对准了,但建筑是一片纯白,和白色底图几乎融在一起,只能靠阴影分辨。
现象
tileset.json 与瓦片请求全部 200,zoomTo 后能看到建筑体积,
但每个面都是接近 #ffffff 的纯色,没有窗框、楼层线,
侧面和顶面亮度差很小。放大到街道级别仍然没有细节。
原因
白模通常是 b3dm 里只存几何、不带贴图的建筑体块。片元最终颜色由
顶点色、材质基色和光照相乘得到,材质基色默认是白色,顶点色也接近白色。
当场景开启了太阳光照,且瓦片顶点没有法线时,Cesium 会按默认法线(朝上)参与计算,
所有面都拿到接近 1.0 的光照强度,结果就是一片白。
如果同时开了 scene.globe.enableLighting,地形也有了明暗,
更容易误判成“白模本身颜色就这样”。
排查过程
- 把
tileset.enableLighting设为false,看白色是否变暗、轮廓是否出现。 - 临时移除所有影像图层,把
scene.globe.baseColor改成深灰,确认模型不是被底图“吃掉”。 - 打印 batch table 的字段名,确认有没有可用于着色的属性(层数、高度、用途)。
var tileset = await Cesium.Cesium3DTileset.fromUrl('/data/buildings/tileset.json');
viewer.scene.primitives.add(tileset);
tileset.readyPromise.then(function () {
var names = tileset.properties && Object.keys(tileset.properties);
console.log('batch table 字段:', names);
});
解决方案
不需要太阳光照时,直接关掉瓦片光照,让模型以自身颜色平铺显示:
var tileset = await Cesium.Cesium3DTileset.fromUrl('/data/buildings/tileset.json', {
enableLighting: false,
maximumScreenSpaceError: 8
});
需要区分建筑时,用 Cesium3DTileStyle 按 batch table 字段着色。
着色前务必确认字段确实存在,引用不存在的字段不会报错,只会整片保持默认色。
tileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
['${height} > 80', 'color("#b03a2e")'],
['${height} > 40', 'color("#d68910")'],
['true', 'color("#3a7ca5")']
]
},
show: true
});
需要更硬的边界时,把颜色混合模式改为替换,避免叠加环境光导致再次发白:
tileset.style = new Cesium.Cesium3DTileStyle({
color: 'color("#3a7ca5")'
});
tileset.colorBlendMode = Cesium.Cesium3DTilesetColorBlendMode.REPLACE;
验证
切换 enableLighting 前后截图对比,建筑各面应出现明显亮度差;
应用样式后 tileset.style 生效,不同高度的体块呈现不同颜色。
把相机拉到 200 米高度,轮廓线在白色底图上仍然可辨。
一个快速判断法:把 viewer.scene.globe.show = false 关掉地球。
如果模型还是不显示,问题不在光照和配色,回到包围盒与相机方向去查。
如果关掉地球后模型很清楚,就说明是白模和白色背景对比度不足。
经纬志(2026)。《3D Tiles 白模糊成一片白,看不出轮廓》。https://www.jingweizhi.com/cookbook/cesium-3dtiles-white-model.html(访问日期 2026-11-03)。