0、概述

本教程将向您介绍Primitive API 的 Geometry & Appearances(几何体和外观)系统。

这是一个高级主题,用于通过自定义网格、形状、体积和外观扩展CesiumJS,并不适合Cesium初学者。

声明:内容均来自Cesium官方教程,经翻译和整理而成。

原文链接:https://cesium.com/learn/cesiumjs-learn/cesiumjs-geometry-appearances/

一、几何体(Geometry

CesiumJS可以使用Entity(如多边形和椭球)创建不同的几何体类型。

例如,将以下内容复制并粘贴到Hello World Sandcastle示例中,以在球体上创建一个带有条纹图案的矩形。

viewer.entities.add({rectangle: {coordinates: Cesium.Rectangle.fromDegrees(-100, 20, -90, 30),material: new Cesium.StripeMaterialProperty({evenColor: Cesium.Color.YELLOW,oddColor: Cesium.Color.RED,repeat: 10})}})

在本教程中,我们深入了解 Geometry 和 Appearance 类型。

几何定义了Primitive(图元)的结构,即构成图元的三角形、线或点。

Appearance(外观)定义图元的着色,包括其完整的 GLSL 顶点和片元着色器,以及渲染状态。

使用几何图形和外观的好处是:

  • 性能 - 在绘制大量静态图元(例如美国每个邮政编码的多边形)时,直接使用几何图形可以让我们将它们组合成单个几何图形,以减少 CPU 开销并更好地利用 GPU。组合图元是在 Web Worker 上完成的,以保持 UI 响应。
  • 灵活性 - 图元结合了几何和外观。通过解耦它们,我们可以独立地修改每一个。我们可以添加与许多不同外观兼容的新几何图形,反之亦然。
  • 低级访问 - 外观提供对渲染的低级访问,而无需担心 直接使用渲染器的所有细节 。
  • 外观可以很容易地:
  • - 编写完整的 GLSL 顶点和片元着色器。
  • - 使用自定义渲染状态。
  • 还有一些缺点:
  • 直接使用几何图形和外观需要更多的代码和对图形学更深入的理解。实体处于适合映射应用程序的抽象级别;几何图形和外观具有更接近传统 3D 引擎的抽象级别。
  • 组合图元对静态数据有效,但不一定对动态数据有效

让我们使用几何图形和外观重写初始代码示例:

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;// original code
//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 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')})
}));

我们没有使用rectangle entity,而是使用了通用的 Primitive,它结合了几何实例和外观。

目前,除了实例是几何体的容器之外,我们不会区分 Geometry 和 GeometryInstance 。

为了创建矩形的几何图形,即覆盖矩形区域并适合地球曲率的三角形,我们创建了一个 RectangleGeometry。

由于它在表面上,我们可以使用EllipsoidSurfaceAppearance。

这通过基于几何体位于表面上或椭圆体上方的恒定高度这一事实进行假设来节省内存。

二、几何体类型

CesiumJS 支持以下几何图形:

Cesium Sandcastle

三、组合几何体

当我们使用一个图元绘制多个静态几何图形时,我们看到了性能优势。例如,在一个图元中绘制两个矩形。

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()
}));

每个实例都有一个 Color 属性。图元是用PerInstanceColorAppearance 构造的 ,它使用每个实例的颜色属性来确定着色。

组合几何图形允许 CesiumJS 有效地绘制大量几何图形。

四、拾取

实例合并后可以独立访问。为实例指定id,并使用该id确定是否使用Scene.pick拾取实例。

下面的示例创建一个id为my rectangle的实例,并在单击该实例时将消息写入控制台。

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, 30.0, -90.0, 40.0),vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT}),id : 'my rectangle',attributes : {color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)}
});scene.primitives.add(new Cesium.Primitive({geometryInstances : instance,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) && (pick.id === 'my rectangle')) {console.log('Mouse clicked rectangle.');}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

使用id可以避免在构造图元后在内存中保留对完整实例的引用,包括几何图形。

五、几何实例

实例可用于在场景的不同部分定位、缩放和旋转相同的几何体。

这是可能的,因为多个实例可引用相同的Geometry,并且每个实例可以具有不同的modelMatrix

这允许我们只计算一次几何图形并多次重复使用它。

下面的示例创建一个EllipsoidGeometry和两个实例。每个实例都引用相同的椭球几何体,但使用不同modelMatrix,从而使一个椭球位于另一个之上。

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})
}));

六、更新每个实例的属性

将几何图形添加到图元后,更新几何图形的每个实例属性以更改可视化效果。每个实例的属性包括:

  • Color : ColorGeometryInstanceAttribute 决定实例的颜色。图元必须有一个 PerInstanceColorAppearance.
  • Show :确定实例可见性的布尔值 。适用于任何实例。

此示例显示如何更改几何实例的颜色:



var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;var circleInstance = new Cesium.GeometryInstance({geometry : new Cesium.CircleGeometry({center : Cesium.Cartesian3.fromDegrees(-95.0, 43.0),radius : 250000.0,vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT}),       attributes : {color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5))},id: 'circle'
});
var primitive = new Cesium.Primitive({geometryInstances : circleInstance,appearance : new Cesium.PerInstanceColorAppearance({translucent : false,closed : true})
});
scene.primitives.add(primitive);setInterval(function() {var attributes = primitive.getGeometryInstanceAttributes('circle');attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));
},2000);

几何实例的属性可以使用primitive.getGeometryInstanceAttributes从图元中检索。可以直接更改属性的属性。

七、外观(Appearance)

几何定义了结构。图元的另一个关键属性appearance定义了图元的着色,即单个像素的着色方式。

CesiumJS有以下几种Appearance:

外观定义了在绘制图元时在 GPU 上执行的完整 GLSL 顶点和片元着色器。Appearances 还定义了完整的渲染状态,它在绘制图元时控制 GPU 的状态。
我们可以直接定义渲染状态,也可以使用更高级别的属性,如closed和translucent,外观将转换为渲染状态。例如:
// Perhaps for an opaque box that the viewer will not enter.
//  - Backface culled and depth tested.  No blending.var appearance  = new Cesium.PerInstanceColorAppearance({translucent : false,closed : true
});// This appearance is the same as above
var anotherAppearance  = new Cesium.PerInstanceColorAppearance({renderState : {depthTest : {enabled : true},cull : {enabled : true,face : Cesium.CullFace.BACK}}
});

一旦外观被创建,我们就不能改变它的 renderState 属性,但我们可以改变它的 material。我们还可以更改图元的 外观 属性。

大多数外观还具有 flat 和 faceForward 属性,它们间接控制 GLSL 着色器。

  • flat  - 平面着色。不考虑照明。

  faceForward  - 照明时,翻转法线使其始终面向观察者。避免背面的黑色区域,例如墙的内侧。

八、几何和外观兼容性

并非所有外观都适用于所有几何图形。例如,椭球曲面外观不适用于墙几何图形,因为墙不在球体的表面上。

要使外观与几何体兼容,它们必须具有匹配的顶点格式,这意味着几何体必须具有外观所需的数据作为输入。创建几何图形时,可以提供VertexFormat。

几何图形 vertexFormat 决定了它是否可以与另一个几何图形组合。两个几何图形不必是相同的类型,但它们需要匹配的顶点格式。

为方便起见,外观具有 vertexFormat 属性或 VERTEX_FORMAT 静态常量,可以作为几何体的选项传入。

var geometry = new Cesium.RectangleGeometry({vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT// ...
});var geometry2 = new Cesium.RectangleGeometry({vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT// ...
});var appearance = new Cesium.MaterialAppearance(/* ... */);
var geometry3 = new Cesium.RectangleGeometry({vertexFormat : appearance.vertexFormat// ...
});

资源

在参考文档中,请参阅:

  • All geometries
  • All appearances
  • Primitive
  • GeometryInstance

有关材料的更多信息,请参阅 Fabric 。

有关未来计划,请参阅 几何和外观路线图。

Cesium 几何体和外观(Geometry Appearances)相关推荐

  1. Cesium官方教程8-- 几何体和外观效果

    原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/ 几何体和外观效果(Geometry and Appearances) 这篇教 ...

  2. GPU Gems2 - 3 几何体实例化的内幕(Inside Geometry Instancing)

    文章部分内容摘自 https://zhuanlan.zhihu.com/p/38411575 [章节概览] 本章讨论了在Direct3D中渲染一个几何体的许多独特实例(Instance)的技术细节问题 ...

  3. Cesium: Primitive vs Entity

    Primitive vs Entity Entity Cesium Sandcastle: Variety of available entities 更高级别的数据驱动 API,它使用一致性设计的. ...

  4. Cesium学习笔记

    Cesium简介 Cesium是一个基于JavaScript的开源框架,可用于在浏览器中绘制3D的地球,并在其上绘制地图(支持多种格式的瓦片服务),该框架不需要任何插件支持,但是浏览器必须支持WebG ...

  5. Cesium 深入浅出

    基本概念 Viewer界面介绍及组件显隐 每一个组件的描述如下: Geocoder:**查找位置工具,查找到之后会将镜头对准找到的地址,默认使用微软的Bing地图 HomeButton:**首页位置, ...

  6. cesium实现地形开挖抽出显示

    Cesium 是一个开源的三维地球浏览器,它可以用来展示地形数据.要在 Cesium 中实现地形开挖抽出显示,需要使用 Cesium 的几何体 API. 首先,需要准备地形数据,Cesium 支持多种 ...

  7. cesium 文本标注被遮挡_Cesium中Primitive讲解

    前面介绍了entity方式绘制对象,现在我们开始接触primitive方式,primitive方式更接近渲染引擎底层,由于我对webgl知之甚少,因此primitive接口我现在也是一知半解,写这个博 ...

  8. Cesium中图元Primitive详细介绍及案例

    Cesium从入门到项目实战总目录: 点击 文章目录 Cesium中图元Primitive详细介绍 Cesium中Primitive案例 Cesium中图元Primitive详细介绍 在Cesium中 ...

  9. Cesium原理篇:7最长的一帧之Entity(上)

    之前的最长的一帧系列,我们主要集中在地形和影像服务方面.简单说,之前我们都集中在地球是怎么造出来的,从这一系列开始,我们的目光从GLOBE上解放出来,看看球面上的地物是如何渲染的.本篇也是先开一个头, ...

最新文章

  1. Arcgis API for JavaScript在地图上实现手机定位信息的追踪显示
  2. ASP.NET中WebForms简介与搭建HelloWorld项目
  3. 忘记手机绑定过的UC/交易猫账号怎么找回
  4. 用python自动化玩游戏封号吗_用 Python 自动化办公能做到哪些有趣或有用的事情?...
  5. 154 万 AI 开发者用数据告诉你,中国 AI 如何才能弯道超车?| 中国 AI 应用开发者报告
  6. 四种依恋类型_【工具】成人依恋量类型介绍
  7. Jquery的jqzoom插件的使用(图片放大镜)
  8. system v 消息队列(二)
  9. mysql双向复制_MySQL 双向复制
  10. 【无广告】一位算法工程师从30+场秋招面试中总结出的超强面经——目标检测篇...
  11. 查看Sql Server2016是否激活
  12. 十九、FPGrowth算法介绍
  13. WINPE启动盘的制作
  14. EM最大期望算法与jensen不等式
  15. 35岁是继续做测试,还是回家送外卖?
  16. 自己做的萌萌哒的js宠物挂件~
  17. 【读书笔记】2018《后谷歌时代:大数据的衰落及区块链经济的崛起》
  18. 泰坦尼克号预测python_泰坦尼克号生存预测(python)
  19. 前端实现在线预览文档(pdf、doc文件)
  20. java调用按键精灵安卓_安卓版按键精灵基本功能版

热门文章

  1. Python之缓存刷新
  2. roundrobin来历_golang实现权重轮询调度算法(Weighted Round-Robin Scheduling)
  3. javascript实现在线拼音输入法
  4. 广度搜索解决迷宫问题
  5. Mac电脑贵在何处?
  6. 2020科目一考试口诀_2020考科目一的一套速记顺口溜,科目一简单记住法
  7. java printwriter乱码_HttpServletResponse PrintWriter中文乱码解决方法
  8. 分页插件--PageHelper
  9. 【地雷开荒技能搭配】
  10. 基于SSM甜品店销售管理系统