Cesium学习笔记(六):几何和外观(Geometry and Appearances)
来源:互联网 发布:小清新记账软件 编辑:程序博客网 时间:2024/06/01 10:39
我们先直接来看一个例子
var viewer = new Cesium.Viewer('cesiumContainer');var flag = viewer.entities.add({ rectangle : { coordinates : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), material : new Cesium.StripeMaterialProperty({ evenColor: Cesium.Color.WHITE, oddColor: Cesium.Color.BLUE, repeat: 5 }) }});
这是我们之前的写法,直接创建一个实体对象
而在这一章,我们将会使用几何和外观来创建实体对象,这样更灵活更有效率
首先,还是先看一下,上面那段代码的改造
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;//创建几何图形var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT })});scene.primitives.add(new Cesium.Primitive({ geometryInstances : instance, //使用系统自带的条纹样式 appearance : new Cesium.EllipsoidSurfaceAppearance({ material : Cesium.Material.fromType('Stripe') })}));
这样的写法自然是有优点也有缺点的
优点:
- 性能 - 当绘制大量静态图元时,直接使用几何形状可以将它们组合成单个几何体,以减少CPU开销并更好地利用GPU。并且组合是在网络上完成的,可以保持UI的响应。
- 灵活性 - 基元组合几何和外观。通过解耦,我们可以独立地修改。我们可以添加与许多不同外观兼容的新几何体,反之亦然。
- 低级访问 - 外观提供了接近于渲染器的访问,可以直接使用渲染器的所有细节(Appearances provide close-to-the-metal access to rendering without having to worry about all the details of using the Renderer directly)。外观使其易于:
- 编写完整的GLSL顶点和片段着色器。
- 使用自定义渲染状态。
缺点:
- 代码量增大,并且需要使用者对这方面有更深入的理解。
- 组合几何可以使用静态数据,不一定是动态数据。
- primitives 的抽象级别适合于映射应用程序;几何图形和外观的抽象层次接近传统的3D引擎(Primitives are at the level of abstraction appropriate for mapping apps; geometries and appearances have a level of abstraction closer to a traditional 3D engine)(感觉翻译的不太好的地方都给上了原文)
我们可以用一个primitives画出多个几何图形,这样可以明显能看出性能上的优势
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT })});var anotherInstance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT })});scene.primitives.add(new Cesium.Primitive({ geometryInstances : [instance, anotherInstance], appearance : new Cesium.EllipsoidSurfaceAppearance({ material : Cesium.Material.fromType('Stripe') })}));
对于不同的图形,我们可以单独给它们设置属性,这里,我们使用PerInstanceColorAppearance不同颜色来遮蔽每个实例
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { //(红,绿,蓝,透明度) color : new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 0.8) }});var anotherInstance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8) }});scene.primitives.add(new Cesium.Primitive({ geometryInstances : [instance, anotherInstance], appearance : new Cesium.PerInstanceColorAppearance()}));
可能这样大家还感觉不出来性能上的优势,那我们可以这样
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;var instances = [];//循环创建随机颜色的矩形for (var lon = -180.0; lon < 180.0; lon += 5.0) { for (var lat = -85.0; lat < 85.0; lat += 5.0) { instances.push(new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(lon, lat, lon + 5.0, lat + 5.0), vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 0.5})) } })); }}scene.primitives.add(new Cesium.Primitive({ geometryInstances : instances, appearance : new Cesium.PerInstanceColorAppearance()}));
这里画了2592个不同颜色的矩形,而且速度非常快,这就更明显的看出primitives在性能上的优势了
虽然我们是通过一个primitives来创建的,但是我们可以给每一个几何图形一个id,这样我们就可以单独访问他们了、
var instance = new Cesium.GeometryInstance({ id : "blue rectangle", geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 0.8) }});var anotherInstance = new Cesium.GeometryInstance({ id : "red rectangle", geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8) }});scene.primitives.add(new Cesium.Primitive({ geometryInstances : [instance, anotherInstance], appearance : new Cesium.PerInstanceColorAppearance()}));//获取屏幕事件管理器var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);//监听屏幕输入事件(这里是监听左键点击事件)handler.setInputAction(function (movement) { var pick = scene.pick(movement.position); if (Cesium.defined(pick) ) { switch (pick.id) { case 'blue rectangle': console.log('Mouse clicked blue rectangle.'); break; case 'red rectangle': console.log('Mouse clicked red rectangle.'); break; } }}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
然后我点击两个矩形,控制台就输出了相应的log
当只要改变属性,不需要改变几何形状时候还可以把几何图形的创建给提出来
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;//使用同一个几何图形var ellipsoidGeometry = new Cesium.EllipsoidGeometry({ vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, radii : new Cesium.Cartesian3(300000.0, 200000.0, 150000.0)});var cyanEllipsoidInstance = new Cesium.GeometryInstance({ geometry : ellipsoidGeometry, //不同的模型矩阵改变了位置 modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 150000.0), new Cesium.Matrix4() ), //改变了颜色 attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CYAN) }});var orangeEllipsoidInstance = new Cesium.GeometryInstance({ geometry : ellipsoidGeometry, modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 450000.0), new Cesium.Matrix4() ), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE) }});scene.primitives.add(new Cesium.Primitive({ geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance], appearance : new Cesium.PerInstanceColorAppearance({ //不透明 translucent : false, closed : true })}));
在创建完之后,我们依旧可以动态的修改模型的属性,当然,这需要给模型加上一个id
var viewer = new Cesium.Viewer('cesiumContainer');var scene = viewer.scene;var ellipsoidGeometry = new Cesium.EllipsoidGeometry({ vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, radii : new Cesium.Cartesian3(300000.0, 200000.0, 150000.0)});var cyanEllipsoidInstance = new Cesium.GeometryInstance({ id : 'cyan', geometry : ellipsoidGeometry, modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 150000.0), new Cesium.Matrix4() ), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CYAN) }});var orangeEllipsoidInstance = new Cesium.GeometryInstance({ id : 'orange', geometry : ellipsoidGeometry, modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 450000.0), new Cesium.Matrix4() ), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE) }});var primitive = scene.primitives.add(new Cesium.Primitive({ geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance], appearance : new Cesium.PerInstanceColorAppearance({ //不透明 translucent : false, closed : true })}));setInterval(function() { var attributes1 = primitive.getGeometryInstanceAttributes('cyan'); attributes1.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0})); var attributes2 = primitive.getGeometryInstanceAttributes('orange'); attributes2.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));},1000);
下面列举下cesium中的几何图形和外观,要注意的是有些外观和几何是不兼容的
参考资料:官方文档
阅读全文
3 0
- Cesium学习笔记(六):几何和外观(Geometry and Appearances)
- Cesium学习笔记(五)几何和外观
- geometry-api-java 学习笔记(六)多边形 Envelope
- Cesium学习笔记(2)
- Cesium学习笔记(3)
- Cesium学习笔记(4)
- Cesium学习笔记(5)
- Cesium学习笔记(一):环境配置和首次运行
- Cesium 学习笔记 下载和环境配置
- Cesium教程番外篇--自定义Geometry(一)
- 3D 学习笔记 几何混合 Geometry Blending
- Qt学习笔记外观篇(六):QLabel
- Cesium学习笔记(四): 相机(camera)
- Cesium学习笔记(一)添加实体
- Cesium学习笔记(二)Imagery Provider
- Cesium学习笔记(三)地形
- Cesium学习笔记(四)Camera
- Cesium学习笔记
- PromiseKit 封装异步Api
- Oracle-1
- 安全篇-AES/RSA加密机制
- 分布式爬虫架构设计
- 计算机网络读书笔记——数据链路层(1)
- Cesium学习笔记(六):几何和外观(Geometry and Appearances)
- Python pip包管理器
- Mybatis-SpringMVC-Spring 用log4j在控制台输出 SQL
- android字体格式设置解决方案
- Android打包生成自定义文件名配置
- Android 中点击某个按钮实现 返回键 的功能
- Java转义字符对照表
- Navicat Premium 连接远程Oracle 数据库12541错误
- Unity狙击枪的视野放大和缩小