自定义瓦片着色器≥0.11.4
loading
three-tile 地图瓦片默认使用MeshStandardMaterial材质,可以使用自定义材质实现地图特效。
1. 步骤
内置的影像加载器TileMaterialLoader(包括其子类)有一个material属性,所有瓦片材质均从该材质 clone() 得来,修改此material属性不仅可以改变瓦片默认风格,还可以使用自定义着色器替换材质,利用着色器实现各种特效。自定义瓦片着色器步骤如下:
- 编写自定义着色器材质
- 获取加载器实例
- 修改加载器的
material属性
2. 代码
- 写一个简单的着色器,将地图反色、降低饱和度,并与原地图色混合:
ts
// 定义着色器
class Filter extends THREE.MeshBasicMaterial {
constructor(params) {
super(params);
this.onBeforeCompile = (shader) => {
// 修改片段着色器
shader.fragmentShader = shader.fragmentShader.replace(
"#include <dithering_fragment>",
`
#include <dithering_fragment>
vec4 texel = texture2D( map, vMapUv );
vec3 inverted = 1.0 - texel.rgb;
float luminance = dot(inverted, vec3(0.299, 0.587, 0.114));
vec3 grayscale = vec3(luminance);
vec3 finalColor = mix(grayscale, inverted, 0.6) * diffuse * 2.0;
gl_FragColor = vec4( finalColor, opacity * texel.a );
`
);
};
}
}- 使用自定义着色器
ts
// 修改影像加载器的材质
const loader = tt.getImgLoader("image");
loader.material = new Filter({ color: 0xaaccff });
map.reload();TIP
每块瓦片的材质均是从该着色器 clone 而来,各个材质没有关联,所以运行时修改材质的属性如颜色,已有瓦片并不会实时响应。如果要实现实时调整颜色等属性的功能,有两种方案:
- 修改材质属性时,遍历所有瓦片修改每个瓦片的材质属性。效率略低,使用 threejs 内置材质时建议使用该方法。
- 重写材质的
copy函数,clone时,将材质的 uniform 以引用方式传递而不是复制,让所有瓦片的材质的 uniform 指向同一个对象。使用自定义着色器时建议使用该方法。