【BIM】BIMFACE中实现构件呼吸灯效果
背景
实现报警呼吸灯效果,目前产品中报警设备仅仅是做了高亮处理,并没有明显的动画效果来提示用户该设备正在报警,bimface
中也提供了构件闪烁的接口,但是看起来比较生硬,查看代码发现是通过定时器实现,比较占用CPU
资源,而呼吸灯报警效果是采用着色器程序编写,通过GPU
执行,性能和效果均优于定时器。
思路
首先,获取到报警设备的包围盒,根据包围盒计算出创建立方体的参数,可以让立方体的尺寸稍微比报警设备大一些,避免因共面而引起花屏的问题,然后通过着色器程序渲染立方体,在requestAnimationFrame
中不停地修改着色器中的统一变量,以实现呼吸灯效果。核心代码如下:
<script type="x-vertexShader" id="vertex">
void main(){
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
</script>
<script type="x-fragmentShader" id="fragment">
uniform float time;
void main(){
gl_FragColor = vec4(0.65,0.0,0.0,abs(sin(time) * 0.85));
}
</script>
var uniform = {
time: {
value: 0.0
}
}
//获取着色器程序
let vertexShader = document.getElementById('vertex').textContent;
let fragmentShader = document.getElementById('fragment').textContent;
//获取报警设备包围盒信息
let max = {
x: 48267.05078125,
y: 145279.40625,
z: 4566.999938964844
};
let min = {
x: 47267.050842285156,
y: 143739.40625,
z: 3833
};
//偏移量
let offset = 100, segment = 2.0;
let width = (max.x - min.x + offset), height = (max.y - min.y + offset), depth = (max.z - min.z + offset);
let targetPos = {
x: (max.x + min.x + offset / segment) / segment,
y: (max.y + min.y + offset / segment) / segment,
z: (max.z + min.z + offset / segment) / segment
};
let boundingBoxGeometry = new THREE.BoxBufferGeometry(width, height, depth);
let boundingBoxMaterial = new THREE.ShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true,
uniforms: uniform
});
let boundingBoxMesh = new THREE.Mesh(boundingBoxGeometry, boundingBoxMaterial);
boundingBoxMesh.position.set(targetPos.x, targetPos.y, targetPos.z);
viewer.addExternalObject("boundingBox", boundingBoxMesh);
//执行动画
function animation() {
uniform.time.value += 0.075;
requestAnimationFrame(animation);
viewer.render();
}
animation();
效果
—— EOF ——
作者:悠扬的牧笛
地址:https://www.cnblogs.com/xhb-bky-blog/p/12961184.html
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。