Cesium: Primitive vs Entity

这篇具有很好参考价值的文章主要介绍了Cesium: Primitive vs Entity。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Primitive vs Entity

Entity

Cesium Sandcastle: Variety of available entities

更高级别的数据驱动 API,它使用一致性设计的、高级别对象来管理一组相关性的可视化对象,其底层也是使用的 primitive

多个类型的实体可以结合使用(如 billboard + label),但同一种实体不能存在多个(如多个 billboard 只能分别创建 entity 实例)。

⚠️ 当在场景中实例化并加载上万个 entity 时,加载速率和性能往往没有有效组织 primitive 来的高。

// i.e. 加载图标
viewer.entities.add({
  position: position,
  billboard: {
    image: "./static/blueCamera.png",
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  },
});

Cesium 支持的 Entity

实体类型 说明
BillboardGraphics 点,广告牌,图片标注
LabelGraphics 点,文字标注
PointGraphics 点,或者填充颜色的圆
CorridorGraphics 走廊:沿着地表的多段线(垂直于表面的折线),且具有一定的宽度,可以拉伸到一定的高度
CylinderGraphics 圆柱、圆锥或者截断的圆锥
EllipseGraphics 椭圆或者拉伸的椭圆
EllipsoidGraphics 椭球体
RectangleGraphics 矩形或者正柱体
PlaneGraphics 平面
PolygonGraphics 多边形,可以具有空洞或者拉伸一定的高度
PathGraphics 多段线,以路径方式呈现,可随时间移动
PolylineGraphics 多段线,可以具有一定的宽度
PolylineVolumeGraphics 多段线柱体
BoxGraphics 立方体
WallGraphics
ModelGraphics gltf 3d 模型
Cesium3DTilesetGraphics 3d tiles tileset

Primitive

Cesium Sandcastle: Variety of available primitives

主要由两部分组成:Geometry(几何结构) 和 Appearance(GLSL 顶点着色器、片段着色器和渲染状态)

面向图形开发人员的底层 API,暴露最小限度的抽象,更多使用图形学术语,具有更大的灵活性。

图元(Primitive)代表场景中的几何体。 几何可以来自单个 GeometryInstance,也可以来自实例数组,即 geometry 来自不同的几何类型。图元将 geometry 实例与描述完整着色的 appearance 相结合,包括 Material 和 RenderState。
粗略地说,geometry 实例定义了结构和位置,appearance 定义了视觉特征。 解耦 geometry 和 appearance,允许我们混合和匹配它们中的大部分,并相互独立地添加新的 geometry 或 appearance 。
将多个实例组合成一个原语称为批处理,可显着提高静态数据的性能。 实例可以单独挑选,Scene#pick 返回它们的 GeometryInstance#id。使用 PerInstanceColorAppearance 设定实例的外观,每个实例可以具有唯一的颜色。
Geometry 可以在 web worker 或主线程上创建和批处理

其具有以下优势:

  1. 性能:绘制大量 Primitive 时,可以将其合并为单个 Geometry,减轻 CPU 负担,更好使用 GPU。
  2. 灵活:GeometryAppearance 解耦,两者可独立修改。

同样的,使用 primitive 就意味着需要编写更多代码,以及对图形学深入的了解。

var instance = new Cesium.GeometryInstance({
  geometry : new Cesium.EllipseGeometry({
    center : Cesium.Cartesian3.fromDegrees(-100.0, 20.0),
    semiMinorAxis : 500000.0,
    semiMajorAxis : 1000000.0,
    rotation : Cesium.Math.PI_OVER_FOUR,
    vertexFormat : Cesium.VertexFormat.POSITION_AND_ST
  }),
  id : 'object returned when this instance is picked and to get/set per-instance attributes'
});

scene.primitives.add(new Cesium.Primitive({
  geometryInstances : instance,
  appearance : new Cesium.EllipsoidSurfaceAppearance({
    material : Cesium.Material.fromType('Checkerboard')
  })
}));

内置几何集合(collection)

⚠️ 为方便使用,cesium 内部提供了一部分常用的可渲染集合对象,在无法满足的情况下再考虑自定义构造

// i.e. 加载多个图标
this.billboards = viewer.scene.primitives.add(
  new Cesium.BillboardCollection()
);

for(let i = 0; i < 10000; i++) {
  this.billboards.add({
    position: position,
    image:  require("./images/blueCamera.png"),
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  });
}
Cesium 内部提供的可渲染图形集合
图形集合 说明
BillboardCollection 图标。为了获得最佳性能,最好选择几个系列,每个系列都有许多图形,而不是许多系列,每个系列只有零星的图形。组织图形,使具有相同更新频率的图形位于同一集合中,如不更改的图形应位于一个集合中,每一帧都变化的图形应该在另一个集合中。
LabelCollection 文字。为了获得最佳性能,参考 BillboardCollection
PointPrimitiveCollection 点。为了获得最佳性能,参考 BillboardCollection
PolylineCollection 多段线。为了获得最佳性能,参考 BillboardCollection
CloudCollection 云特效

Geometry - 几何体

Cesium 支持的 Geometry
几何图形 轮廓几何图形 类别 说明
BoxGeometry BoxOutlineGeometry 立方体 立方体
CircleGeometry CircleOutlineGeometry 圆形 圆形或者拉伸的圆形,圆圈或挤压圆
CorridorGeometry CorridorOutlineGeometry 走廊 走廊:沿着地表的多段线(垂直于表面的折线),且具有一定的宽度,可以拉伸到一定的高度
CylinderGeometry CylinderOutlineGeometry 圆柱、圆锥 圆柱、圆锥或者截断的圆锥
EllipseGeometry EllipseOutlineGeometry 椭圆 椭圆或者拉伸的椭圆
EllipsoidGeometry EllipsoidOutlineGeometry 椭球体 椭球体
RectangleGeometry RectangleOutlineGeometry 矩形 矩形或者拉伸的矩形
PolygonGeometry PolygonOutlineGeometry 多边形 多边形,可以具有空洞或者拉伸一定的高度
PolylineGeometry SimplePolylineGeometry 多段线 多段线,可以具有一定的宽度
PolylineVolumeGeometry PolylineVolumeOutlineGeometry 多段线柱体 多段线柱体
SphereGeometry SphereOutlineGeometry 球体 球体
WallGeometry WallOutlineGeometry

Geometry Instances - 几何体实例

相当于 Geometry 的容器,而多个 Instance 可以公用一个 Geomotry 并利用 GeometryInstance.modelMatrix 提供多种属性信息。

var geometry = Cesium.BoxGeometry.fromDimensions({
  vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,
  dimensions: new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0)
});

var instanceBottom = new Cesium.GeometryInstance({
  geometry: geometry,
  modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
  },
  id : 'bottom'
});

var instanceTop = new Cesium.GeometryInstance({
  geometry: geometry,
  modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 3000000.0), new Cesium.Matrix4()),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
  },
  id : 'top'
});
Combing Geometries - 合并几何图形✨

我们可以合并多个 Instance 为一个 Primitive,提高我们的性能。

⚠️ 但是不同类别的几何图形不能放一起!如 Outline 为一类 geometryInstances,非轮廓的为另一类

// 填充面几何实例
var instances = [Instance1, Instance2, Instance3, ……];
scene.primitives.add(new Cesium.Primitive({
  geometryInstances: instances, //合并
  // 某些外观允许每个几何图形实例分别指定某个属性,例如:
  appearance: new Cesium.PerInstanceColorAppearance({translucent: false, closed: true})
}));

// 轮廓几何实例
var outlineInstances = [OutlineInstance1, OutlineInstance2, OutlineInstance3, ……];
scene.primitives.add(new Cesium.Primitive({
  geometryInstances: outlineInstances, //合并
  // 某些外观允许每个几何图形实例分别指定某个属性,例如:
  appearance: new Cesium.PerInstanceColorAppearance({translucent: false, closed: true})
}));
更新单个 Instance 属性

在添加到 Primitive 后,我们仍然可以通过 Id 获取指定 Instance 并修改其属性。

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 )),
    show: new Cesium.ShowGeometryInstanceAttribute(true) //显示或者隐藏
  },
  id: 'circle'
});

var primitive = new Cesium.Primitive({
  geometryInstances: circleInstance,
  appearance: new Cesium.PerInstanceColorAppearance({
    translucent: false,
    closed: true
  })
});
scene.primitives.add(primitive);

var attributes = primitive.getGeometryInstanceAttributes('circle'); //获取某个实例的属性集
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({
  alpha: 1.0
}));

Appearance - 外观

⚠️ 注意:有些外观和几何是不兼容的。 例如 EllipsoidSurfaceAppearanceWallGeometry 就不能搭配,原因是后者是垂直于地表的。即使外观与几何图形兼容,它们还必须有匹配的顶点格式(vertex formats)—— 即几何图形必须具有外观可以作为输入的数据格式,在创建 Geometry 时可以提供 VertexFormat

Cesium 支持的 Appearance
外观 描述
MaterialAppearance 支持各种 Geometry 类型的外观,支持使用材质来定义着色。支持材料描述阴影。
EllipsoidSurfaceAppearance MaterialAppearance 的一个版本。假设几何图形与地表是平行的,并且依此来进行顶点属性(vertex attributes)的计算。和 Material Appearance 一样,就像一个多边形,并且使用这个假设来通过程序上计算许多顶点属性来节省内存。
PerInstanceColorAppearance 让每个实例使用自定义的颜色来着色,使用每个实例的颜色来遮蔽每个实例。
PolylineMaterialAppearance 支持使用材质来着色多段线。支持材料遮蔽 Polyline。
PolylineColorAppearance 使用每顶点或者每片段(per-vertex or per-segment )的颜色来着色多段线—使用每顶点或每段着色来遮蔽折线

Appearance 定义了需要在 GPU上 执行的 GLSL 着色器,这部分一般只有在自定义外观时需要修改。

render state 用来在绘制 Primitive 的时候控制 GPU 状态,一旦外观被创建,render state 就不能再改变了,但是我们可以修改其材质。

//下面的外观可用于定义一个 Viewer 可进入的透视盒子
var appearance = new Cesium.PerInstanceColorAppearance({
  translucent: true,
  closed: true
});

//下面的代码效果同上
var appearance1 = new Cesium.PerInstanceColorAppearance({
  renderState: {
    depthTest: {
      enabled: true
    },
    cull: {
      enabled: true,
      face: Cesium.CullFace.BACK
    }
  }
});

自定义着色器(示例:雷达动效)

Cesium: Primitive vs Entity

/** 1. 数据准备 */
// 雷达的高度
var length = 400000.0;
// 地面位置(垂直地面)
 var positionOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9);
// 中心位置
var centerOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9, length*0.5);
// 顶部位置(卫星位置)
var topOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9,length);
// 矩阵计算
var modelMatrix = Cesium.Matrix4.multiplyByTranslation( // 转换矩阵
  Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid), // 矩阵
  new Cesium.Cartesian3(0.0, 0.0, length * 0.5), // 要转换的笛卡尔坐标
  new Cesium.Matrix4() // 返回新的矩阵
 );

/** 2. Geometry: 创建一个圆锥几何图形 */
//1. 构造 geometry
var cylinderGeometry = new Cesium.CylinderGeometry({
  length: length,
  topRadius: 0.0,
  bottomRadius: length * 0.5,
  vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat
});
//2. 创建 GeometryInstance
var redCone = new Cesium.GeometryInstance({
  geometry: cylinderGeometry, //geomtry类型
  modelMatrix: modelMatrix, //模型矩阵 调整矩阵的位置和方向
});

**/** 3. shader着色器: 定义glsl代码 */**
const source =
//传入的动态数值
`uniform vec4 color;
 uniform float repeat;
 uniform float offset;
 uniform float thickness;

//设置图形外观材质
czm_material czm_getMaterial(czm_materialInput materialInput){
    czm_material material = czm_getDefaultMaterial(materialInput); //获取内置的默认材质
    float sp = 1.0/repeat; //重复贴图
    vec2 st = materialInput.st; //二维纹理坐标
    float dis = distance(st, vec2(0.5)); //计算距离
    float m = mod(dis + offset, sp); //间隔
    float a = step(sp*(1.0-thickness), m);//线条拼色
 //修改材质
    material.diffuse = color.rgb;
    material.alpha = a * color.a;
 return material;
}`

/** 4. appearance */
//1. 自定义material外观材质,修改着色器
const material = new Cesium.Material({
 fabric: {
  type: 'VtxfShader1',
  uniforms: { //动态传递参数
   color: new Cesium.Color(0.2, 1.0, 0.0, 1.0),
   repeat: 30.0,
   offset: 0.0,
   thickness: 0.3,
  },
  source :source
  },
  translucent: false
})
//2. 定义appearance外观
const appearance = new Cesium.MaterialAppearance({
 material:material, // 自定义的材质
 faceForward : false, // 当绘制的三角面片法向不能朝向视点时,自动翻转法向,从而避免法向计算后发黑等问题
 closed: true // 是否为封闭体,实际上执行的是是否进行背面裁剪
})

/** 5. 创建 Primitive */
//1. 添加 Primitive
var radar = viewer.scene.primitives.add(
  new Cesium.Primitive({
  geometryInstances: [redCone],
  appearance:appearance
 })
);
//2. 动态修改雷达材质中的 offset 变量,从而实现动态效果。
viewer.scene.preUpdate.addEventListener(function() {
 let { offset } = radar.appearance.material.uniforms;
  offset -= 0.001;
 if (offset > 1.0) {
  offset = 0.0;
 }
 radar.appearance.material.uniforms.offset = offset;
})

参考资料

Cesium | Primitive图元介绍及与Entity对比 - 掘金
Cesium | 海量点的加载与性能优化 - 掘金
Part I: Custom Geometry & Appearances – Cesium
Part II: Geometry and Appearances · CesiumGS/cesium Wiki
Cesium原理篇:Material - fu*k - 博客园
cesium| Primitive图元自定义着色器(1) | 一只咸鱼 | 努力学习最新姿势!!!文章来源地址https://www.toymoban.com/news/detail-409432.html

到了这里,关于Cesium: Primitive vs Entity的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Cesium entity 渐隐渐显、闪烁

     点entity 面entity 

    2024年02月13日
    浏览(33)
  • Cesium Entity、dataSource添加与删除

    在Cesium中,要添加和删除实体和数据源可以使用以下代码: 1. 添加实体

    2024年02月10日
    浏览(37)
  • cesium-2-entity(包含gltf创建)

    viewer -- datasources(DataSourceCollection类型) -- datasource -- entities(EntityCollection类型) -- entity 需要学习的方向是:只需要注意每个层与层之间的关系和entity实例如何创建即可 增: add(dataSource) → Promise.DataSource 删:(destroy一般为boolean,指是否需要直接销毁该datasource) remove(dataSource,

    2024年02月01日
    浏览(44)
  • Cesium 视角切换到实体(entity)/ dataSources / 定位到模型(3DTiles)

    Cesium 的 camera.flyTo 是不可以直接飞到实体的。但是 viewer.flyTo 可以直接飞到实体。 viewer.flyTo (target, options) :将相机飞到提供的实体、实体或数据源。如果数据源仍在加载过程中或可视化仍在加载中,则此方法在执行飞行之前等待数据准备好 viewer.flyTo 的 target` 可以是:要查看

    2024年02月11日
    浏览(43)
  • 15. 成功解决:java: Can‘t generate mapping method with primitive return type.

    ❤️ 个人主页:水滴技术 🌸 订阅专栏:成功解决 BUG 合集 🚀 支持水滴: 点赞 👍 + 收藏 ⭐ + 留言 💬 今天启动 SpringBoot 项目时,报了如下错误: java: Can\\\'t generate mapping method with primitive return type. 仔细一下,还不止这一个错误,错误截图: 通过错误描述信息来看,应该是

    2024年02月15日
    浏览(36)
  • MyBatis 使用报错: Can‘t generate mapping method with primitive return type

    今天在新项目中使用 MyBatis 报如下错误: Can\\\'t generate mapping method with primitive return type 发现是 @Mapper 注解引入错误,错误引入 org.mapstruct.Mapper , 实际应该引入 org.apache.ibatis.annotations.Mapper 正确引入注解: org.apache.ibatis.annotations.Mapper 👋 你好,我是 Lorin 洛林,一位 Java 后端技术

    2024年01月20日
    浏览(37)
  • 【Vue】Cannot set reactive property on undefined,null,or primitive value:undefined

    技术栈:vue + element 报错内容: Cannot set reactive property on undefined, null, or primitive value:undefined 如下图所示: 根据报错内容翻译一下,就是不能对 undefined,null 或者原始值为 undefined 的属性设置值。大白话就是不能对字段为 undefined,null 进行赋值,vue 是双向数据绑定。 总的来说,我

    2024年01月18日
    浏览(54)
  • List<Entity>与Map<String, Entity>互转

    List 转为 MapString, Entity 要将 ListEntity 转换为 MapString, Entity,你需要指定一个属性作为 Map 的键,然后将 List 中的每个实体对象的该属性值作为键,实体对象本身作为值放入 Map 中。以下是一个示例代码: 假设你有一个名为 Entity 的实体类,其中有一个属性名为 id ,你想将 Lis

    2024年04月22日
    浏览(35)
  • 解决Mapper method ‘com.xxx‘ attempted to return null from a method with a primitive return type (xxx)

    今天写完 页面按钮排序 接口,如下代码所示:

    2024年02月05日
    浏览(83)
  • 《论文阅读》SetGNER:General Named Entity Recognition as Entity Set Generation

    不知道是不是大模型的流行还是什么其他原因,导致现在网上都没有人来分享NER模型的相关论文了~ 本文方法简单,代码应该也比较简单(但是没见作者放出来)。 推荐指数:★★☆☆☆ 处理三种不同场景的NER 与 sequence-to-sequence NER 方法不同,本模型不需要强制实体按照顺序

    2023年04月21日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包