自定义瓦片着色器
loading
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>",
`
vec4 texel = texture2D( map, vMapUv );
vec3 inverted = mix(texel.rgb, 1.0 - texel.rgb, 1.0);
float luminance = dot(inverted, vec3(0.299, 0.587, 0.114));
vec3 grayscale = vec3(luminance);
vec3 finalColor = mix(grayscale, inverted, 0.6) * diffuse;
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 指向同一个对象。使用自定义着色器时建议使用该方法。