基本原理就是把Element作为贴图贴到自定义的材质里。这样可以方便使用shader等对材质做进一步处理。直接使用Entity加入局限性比较大。
1、使用video标签播放视频
其中样式不能display: none或者移出窗口外,否则在cesium内只能渲染第一帧。所以直接把透明度设置为全透明 opacity: 0;
<video crossorigin="anonymous" style="width: 100px; height: 100px; position: fixed; top: 0; opacity: 0;" id="v" loop="" class="video-js" autoplay="autoplay" preload="auto" muted>
<source src="x">
</video>
// js
let videoElement = document.getElementById('v');
2、创建自定义材质
let m =new Material({
fabric: {
uniforms: {
image: "",
},
source: shaderSource
}
})
m.uniforms.image = videoElement;
直接使用new的方式初始化材质对象。在初始化完成后我们再通过uniforms
传入视频节点。其中fabric.source 为shader的代码
可以写一个最简单的shader:
let shaderSource = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = texture(image, materialInput.st).rgb;
return material;
}
`
czm_getMaterial
是内置的入口函数,return的内容是显示的结果。
然后就是创建Primitive并添加到view
await GroundPrimitive.initializeTerrainHeights()
const primitive = new GroundPrimitive({
asynchronous: false,
geometryInstances: new GeometryInstance({
geometry: new PolygonGeometry({
polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray([
110.50940051824507, 25.652613985682056,
110.53054820489356, 25.625936676583187,
110.5577535658818, 25.641588383493374,
110.54154406073128, 25.6676382250381,
]))
})
}),
appearance: new MaterialAppearance({
// closed: false,
material: m,
renderState: {
blending: BlendingState.ALPHA_BLEND
}
// renderState: {
// blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
// depthTest: { enabled: true },
// depthMask: true,
// },
})
})
let p = viewer.scene.primitives.add(primitive)
polygonHierarchy的坐标就是相当于视频的显示位置控制点。
如果 GroundPrimitive 的 sync是false, 那么需要 同步等待初始化完成 await GroundPrimitive.initializeTerrainHeights()
创建一个MaterialAppearance并把我们的材质传进去。