为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Java


原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/

几何体和外观效果(Geometry and Appearances)

这篇教程会教大家学习Primitive API中支持的几何体和外观效果。这篇教程并不是面向Cesium的普通用户,主要讨论Cesium的高级知识,包括自定义三角网(mesh),形状(shape),体(volume)以及他们的外观。如果你是初学者,建议先学下这篇教程。

Cesium可以使用Entity创建不同的几何体,比如多边形和椭圆等。比如把下面代码拷贝到 Sandcastle 的Hello World 就能创建一个带条纹状材质的矩形:

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

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

条纹矩形

这篇教程里,我们深入到图元内部,使用 Geometry类和 Appearance 类来创建效果。几何体定义了图元的结构,比如三角网、线、点等。外观(appearance)定义了图片的着色效果,包含完整的顶点(vertex)和片段(fragment)着色器(shader)以及着色器状态。

Cesium支持下列几何体:

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

Box Geometry

BoxGeometry

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

Box Outline Geometry

BoxOutlineGeometryA box

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

Circle Geometry

CircleGeometry

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

Circle Outline Geometry

CircleOutlineGeometry

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

Corridor Geometry

CorridorGeometry

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

Corridor Outline Geometry

CorridorOutlineGeometry 以米为单位的折线 和 一个挤压高度

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

Cylinder Geometry

CylinderGeometry

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

Cylinder Outline Geometry

CylinderOutlineGeometry圆柱, 椎体,半椎体

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

Ellipse Geometry

EllipseGeometry

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

Ellipse Outline Geometry

EllipseOutlineGeometry椭圆或者垂直挤压的椭圆

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

Ellipsoid Geometry

EllipsoidGeometry

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

Ellipsoid Outline Geometry

EllipsoidOutlineGeometry椭球体

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

Extent Geometry

RectangleGeometry

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

Extent Outline Geometry

RectangleOutlineGeometry矩形或者垂直挤压矩形

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

Polygon Geometry

PolygonGeometry

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

Polygon Outline Geometry

PolygonOutlineGeometry多边形,支持带洞以及垂直挤压

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

Polyline Geometry

PolylineGeometry

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

Polyline Outline Geometry

SimplePolylineGeometry像素宽度定义的折线段

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

Volume Geometry

PolylineVolumeGeometry

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

Volume Outline Geometry

PolylineVolumeOutlineGeometry一个二维图形沿着折线的延伸体。

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

Sphere Geometry

SphereGeometry

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

Sphere outline Geometry

SphereOutlineGeometry球体

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

all Geometry

WallGeometry

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

Wall Outline Geometry

WallOutlineGeometry垂直于地表的墙面

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

几何体全家福

使用几何体和外观的优势:

性能 - 尤其是绘制大量静态图元(比如整个美国的邮政编码区域多边形),使用几何体可以把他们组合成一个单一的几何体,这样会减少cpu的开销,并且充分利用GPU的能力。组合几何体可以在web worker中完成,不会影响用户界面的响应。

灵活性 - 图元由几何体和外观构成。不过他们可以单独修改。新建的几何体可以兼容多种不同的外观,反之亦然。

底层访问 - 外观提供了近乎最底层的渲染访问,但是又不需要直接担心渲染 Renderer 的细节技术 。外观使下面的技术简单了很多:

编写完整的顶点和片段着色器GLSL代码。

使用用户自定义的渲染状态。

当然也有一些缺点:

使用几何体和外观需要写更多的代码,并且需要对图形知识有深刻的理解。Entity是应用层的抽象;而几何体和外观更像是一个传统3D引擎的级别。

对于静态数据,几何体合并非常有效,但是对于动态数据不适合。

使用几何体和外观来重新编写示例代码:

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

没有用矩形的entity,我们使用了普通的 Primitive, 它里面连接和几何体和外观。现在先忽略 Geometry和 a GeometryInstance 的区别,只需知道instance是geometry的容器。

创建矩形几何体 RectangleGeometry的时候,这个矩形区域的三角网会贴合地球曲率。

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

网格效果

因为我们预先知道这个几何体是在球面上,所以直接使用 EllipsoidSurfaceAppearance。这样做也能节省内存 ,支持所有的材质,因为几何体是在椭球体上方的固定高度(译者注:个人理解是说顶点可以只需要二维坐标,高度值可以当作uniform传进去)。

几何体合并

当使用一个图元去绘制多个静态几何体的时候,会有些效率提升。比如我们画两个矩形:

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

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

两个矩形

创建了另一个矩形的instance,然后把两个instance都添加到一个图元里,使用同一个外观去绘制。 一些外观允许为每个instance设置不同的属性(attribute)。比如,使用 PerInstanceColorAppearance 对每个instance着不同颜色。

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

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

不同颜色的矩形

每个intance有一个Color 属性。图元里创建一个PerInstanceColorAppearance,它知道使用每个instance的color属性去着色。

几何体合并允许Cesium高效的渲染大量几何体。下面示例绘制了2592个不同颜色的矩形。优化之后,渲染非常块。

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

}));

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

几何体合并

拾取

当instance合并之后,仍然支持独立访问。通常,我们会设置一个id属性, Scene.pick函数里通过它来判定哪个instance被拾取。这个id 可以任何js类型:字符串,数字,带属性的对象等等。

下面的示例创建一个带id 的instance,当它被点击的时候控制台会输出一个消息。

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

使用id 而不是用instance对象本身去判定,主要是为了避免在创建图元之后,我们的图元甚至我们的项目对所有的instance对象 以及 它的几何体 一直被引用无法释放内存。因为几何体一般包含了一个比较大的数组,这种方式就可以帮我们节省大量内存。

几何体intances

目前为止,我们创建的每个几何体instance都只包含一个几何体。此外,instance竟然用来把同一个几何体放置在场景的不同位置,包括不同大小和方向。由于多个instance可以引用同一个几何体( Geometry),而每个instance可以有不同的偏移矩阵(modelMatrix)。这样,我们就只需要计算一次几何体(计算顶点等)而多次使用它。

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

几何体 instance

下面的代码创建了一个EllipsoidGeometry 和 两个instance. 每个instance 引用了相同的椭球几何体,但是使用 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

})

}));

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

椭球体instances

更新每个instance的属性

即便是已经添加到图元里,每个instance的一些属性也可以修改,包括:

Color : ColorGeometryInstanceAttribute 决定了几何体颜色。不过图元应该设置一个 PerInstanceColorAppearance外观。

Show :布尔变量决定instance是否可见,对任意instance都有效。

下面代码演示如何修改几何体instance的颜色:

This example shows how to change the color of the geometry instance:

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来获取到。attributes 里的值可以直接修改。这里,我们每2秒钟设置'circle'这个几何体随机颜色。

外观(Appearances)

几何体定义了结构。图元的另一个关键属性是appearance,决定图元的着色,也就说每个像素是如何上色的。一个图元可以有若干个几何体instance,但是只能有一个appearance属性。根据appearance类型不同,一个appearance可能有一个 material 属性,材质属性决定了大体的着色( the bulk of the shading)。

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

Appearances

Cesium 包含下述外观类型:

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

MaterialAppearance

MaterialAppearance 所有几何体都使用同一个外观,支持使用 materials 去定义着色效果.

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

EllipsoidSurface

EllipsoidSurface MaterialAppearance 的简化版本,假定几何体都和地球椭球体平行,就像多边形一样。使用这个可以在计算大量顶点属性的时候节省内存

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

PerInstanceColorAppearance

PerInstanceColorAppearance 每个instance使用不同的颜色去着色。

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

PolylineMaterialAppearance

PolylineMaterialAppearance 支持在折线上设置材质。

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

PolylineColorAppearance

PolylineColorAppearance支持折线在每个顶点或者每一段设置颜色。

外观完整的定义了顶点和片段着色器代码,在GPU中图元渲染的时候使用。除非要自定义外观,否则我们很少使用它们。外观也定义了完整的渲染你状态,它控制了图元渲染时候的GPU状态。我们可以使用高级的属性来定义渲染状态,比如 闭合closed 和 半透明translucent,外观会把他们转换为真正的底层状态,比如:

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

一旦我们的外观创建了,我们不能修改它的renderState属性,但是我们能修改它的材质 material。当然,我们可以整个替换图元的appearance属性。

大部分外观包含 flat 和faceForward 属性, 这个直接控制了GLSL的着色效果。

flat - 纯色着色,不考虑光照效果。

faceForward - 当有光照的的时候,当视图正对它的时候反转法向量,避免墙体的背面是黑色的。

flat : true | faceForward : false | faceForward : true |

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

flat:true

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

faceForward : false

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

faceForward : true

几何体和外观的匹配性

我们发现不是所有的外观都能作用在任意几何体上。比如EllipsoidSurfaceAppearance 不能用在WallGeometry 上,因为墙永远垂直地表,而不是平行地表。

隐含之意,一个外观能和一个几何体匹配,需要顶点格式匹配,也就是说几何体必须包含外观需要的顶点格式数据。创建一个几何体的时候,可以指定一个 VertexFormat 参数。

有时候为了简化问题,但是接受一点点浪费和效率低,可以计算一个几何体的所有顶点属性格式,这样就能和所有外观兼容(忽略per-instance属性)

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

不兼容

如果使用EllipsoidSurfaceAppearance,比如我们只创建了顶点的位置属性,那么就会崩溃(get away)。

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

通常,我们怎么知道某种外观需要哪种顶点格式?大部分外观都有一个 vertexFormat 属性, 甚至一个 VERTEX_FORMAT静态常量。

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

同样,几何体的 vertexFormat 属性也决定了几何体是否可以合并。如果要合并,可以几何体类型不同,但是必须保证顶点格式一致。

相关资源

用户手册:

所有几何体

所有外观

图元Primitive

几何体instanceGeometryInstance

想了解材质的更多内容,请访问Fabric。

想了解这块的开发计划,请访问: Geometry and Appearances Roadmap.Cesium官方教程8-- 几何体和外观效果

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

©著作权归作者所有:来自51CTO博客作者cesium实验的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消