tft每日頭條

 > 科技

 > cesium怎麼添加自定義模型

cesium怎麼添加自定義模型

科技 更新时间:2024-08-22 15:33:11

在基礎篇中我們講過空間數據可視化之Entity實體類,今天我們介紹另外一個比較接近渲染引擎底層的類Primitive,雖然兩者都可用于繪制同樣的幾何圖形,但考慮到性能問題,我們更推薦您使用Primitive類實現。在使用Primitive API之前,您最好具備WebGL基礎知識,如果對WebGL不是太了解,建議先學習《WebGL編程指南》這本書。

Primitive介紹

1. Primitive組成Primitive由兩部分組成:幾何形狀(Geometry)和外觀(Appearance)。幾何形狀定義了Primitive的結構,例如三角形、多邊形、折線、點、标簽等;外觀則定義了Primitive的着色或渲染(Shading),包括GLSL(OpenGL着色語言,OpenGL Shading Language)頂點着色器和片元着色器( vertex and fragment shaders),以及渲染狀态(render state)。

2. Primitive優劣勢相對于Entity,使用Primitive具有以下優勢:(1)性能:繪制大量Primitive時,可以将其合并為單個Geometry以減輕CPU負擔、更好地使用GPU。合并Primitive由web worker線程執行,以保持UI響應性;(2)靈活性:Geometry與Appearance 解耦,兩者可以分别進行修改;(3)低級别訪問:易于編寫GLSL頂點、片段着色器、使用自定義的渲染狀态 。

同時,也具有以下劣勢:(1)需要編寫更多的代碼,并且對圖形編程有更深刻的理解,尤其是OpenGL知識;(2)需要對組合幾何形狀對于靜态數據有效,而對于動态數據則不一定有效。

3.幾何圖形繪制方式以下是通過Entity和Primitive兩種方式繪制矩形圖形的方法:

// Entity方式 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 }) } }); // Primitive方式 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') }) }));

幾何Geometry

1.支持的幾何類型從基礎篇的Entity篇幅我們知道,Entity支持的圖形類型是以Graphics結尾的,一共有17種類型。而Primitive支持的幾何類型則是以Geometry結尾的,和Entity除了結尾命名不一樣之外,Cesium中還提供了獨有的點形狀PointPrimitive和一些形狀的集合,包括PointPrimitiveCollection、BillboardCollection、LabelCollection、PolylineCollection。支持的形狀如下圖所示:

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)1

添加簡單的點圖元集合方法如下:

//CreateapointPrimitivecollectionwithtwopoints varpoints=scene.primitives.add( newCesium.PointPrimitiveCollection({ modelMatrix:Cesium.Matrix4.IDENTITY, debugShowBoundingVolume:false, //OPAQUE完全不透明;TRANSLUCENT完全透明;OPAQUE_AND_TRANSLUCENT不透明和半透明 blendOption:Cesium.BlendOption.OPAQUE_AND_TRANSLUCENT, }) ); //addPointPrimitive points.add({ position:Cesium.Cartesian3.fromDegrees(-75.59777,40.53883,1000.0), color:Cesium.Color.YELLOW, }); points.add({ position:Cesium.Cartesian3.fromDegrees(-74.59777,40.53883,1000.0), color:Cesium.Color.CYAN, });

2.貼地或貼模型特性跟Entity類似,Primitive也支持貼地或貼模型的特性,但不一樣的是,Primitive是通過classificationType屬性控制的。其中GroundPolylineGeometry、GroundPolylinePrimitive結合實現貼地線;GroundPrimitive實現貼地幾何形狀,包括CircleGeometry、CorridorGeometry、EllipseGeometry、PolygonGeometry、RectangleGeometry;ClassificationPrimitive可實現貼地或貼模型,包括BoxGeometry、CylinderGeometry、EllipsoidGeometry、PolylineVolumeGeometry、SphereGeometry幾何形狀。下面為一簡單的貼模型示例:

scene.primitives.add( newCesium.ClassificationPrimitive({ geometryInstances:newCesium.GeometryInstance({ geometry:Cesium.BoxGeometry.fromDimensions({ vertexFormat:Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, dimensions:newCesium.Cartesian3(8.0,5.0,8.0), }), modelMatrix:modelMatrix, attributes:{ color:Cesium.ColorGeometryInstanceAttribute.fromColor( newCesium.Color(1.0,0.0,0.0,0.5) ), show:newCesium.ShowGeometryInstanceAttribute(true), }, id:"volume", }), classificationType:Cesium.ClassificationType.CESIUM_3D_TILE, }) );

3.組合幾何當我們使用一個圖元繪制多個靜态幾何圖形時,我們就會看到性能的優勢。組合多個GeometryInstances 為一個Primitive可以極大地提高性能,以下示例繪制了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() }));

4.實例化幾何實例化可用于在場景的不同部分定位、縮放和旋轉相同的幾何體。多個實例可以引用相同的Geometry,并且每個實例可以具有不同的modelMatrix。這允許我們隻需計算一次幾何圖形,并多次重複使用它。

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)2

下面的示例創建一個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 }) }));

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)3

5.更新每個示例的屬性在将幾何圖形添加到Primitive中以後,仍然可以修改幾何圖形實例的某些屬性:(1)顔色:如果Primitive設置了PerInstanceColorAppearance外觀,則可以修改ColorGeometryInstanceAttribute類型的顔色(2)可見性:任何實例可以修改可見性

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

外觀Apperance

Primitive由兩個重要部分組成:幾何圖形實例、外觀。一個Primitive可以有多個幾何實例,但隻能有一個外觀。幾何圖形定義了結構,外觀定義了每個像素如何被着色,外觀可能直接使用材質(Material)。一個Primitive結構組成如下圖所示:

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)4

同時,Cesium定義了以下外觀:

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)5

外觀定義了需要在GPU上執行的完整的GLSL頂點、片段着色器,通常不需要修改這一部分,除非需要定義自己的外觀。外觀還定義了完整的渲染狀态,用于在繪制Primitive時控制GPU的狀态,我們可以直接或者通過高層API來定義渲染狀态,如“閉合(closed)”和“半透明(translucent)”,外觀将轉換為渲染狀态。如右圖所示:

//下面的外觀可用于定義一個不可進入的不透明的盒子 varappearance=newCesium.PerInstanceColorAppearance({ translucent:false, closed:true, }); //下面的代碼效果同上 varanotherAppearance=newCesium.PerInstanceColorAppearance({ renderState:{ depthTest:{ enabled:true, }, cull:{ enabled:true, face:Cesium.CullFace.BACK, }, }, });

創建外觀後,不能更改其renderState屬性,但可以更改其material。我們還可以更改primitive的appearnace屬性。。大部分外觀具有flat、faceForward屬性,可以間接地控制GLSL着色器:(1)flat:扁平化着色,不考慮光線的作用(2)faceForward:布爾值,控制光照效果

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)6

着色器shadershader即着色器,分為頂點着色器(Vertex Shader)、片元着色器(Fragment Shader)、幾何着色器(Geometry shader)、計算着色器(Compute shader)、細分曲面着色器(Tessellation or hull shader),其中可編程的是頂點着色器和片元着色器。示意圖如下:

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)7

在屏幕上繪制或顯示一些物體時,這些物體的顯示形式是圖元(Primitive)或者網格(Mesh),比如一個貼在網格上的紋理角色。

幾何和外觀兼容性

并非所有外觀都适用于所有幾何圖形。例如,EllipsoidSurfaceAppearance外觀不适用于WallGeometry幾何圖形,因為牆不在球體的表面上。要使外觀與幾何圖形兼容,它們必須具有匹配的頂點格式,這意味着幾何圖形必須具有外觀所期待的輸入數據。創建幾何圖形時可以提供vertexFormat。

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)8

cesium怎麼添加自定義模型(Cesium開發高級篇01空間數據可視化之Primitive)9

幾何圖形的vertexFormat确定它是否可以與其他幾何圖形組合。兩個幾何圖形不必是相同的類型,但它們需要匹配的頂點格式。為方便起見,外觀要麼具有vertexFormat屬性,要麼具有可作為幾何體選項傳入的VERTEX_FORMAT靜态常量。

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

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved