目录
1.Primitive
new Cesium.Primitive ( options )
图元表示
场景
中的几何。几何可以来自单个
GeometryInstance
如下面的示例1所示,或者来自实例数组,即使几何图形来自不同几何类型,例如
RectangleGeometry
和
EllipsoidGeometry
a>如代码示例2所示。
基本体将几何实例与描述完整阴影的
Appearance
组合在一起,包括
材料
和
RenderState
。大致而言,几何实例定义了结构和位置,外观定义了视觉特征。解耦的几何形状和外观使我们能够混合并匹配其中的大多数,并彼此独立地添加新的几何形状或外观。
将多个实例组合成一个原语称为批处理,可显着提高静态数据的性能。可以单独选择实例;
Scene#pick
返回其
GeometryInstance#id
。使用每个实例的外观,例如
PerInstanceColorAppearance
,每个实例也可以具有唯一的颜色。
几何
可以在网络工作者或主线程上创建和批处理。前两个例子显示将通过使用几何描述在Web工作者上创建的几何。第三个例子显示了如何通过显式调用
createGeometry
方法在主线程上创建几何的方法。
Name | Type | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Object |
optionalObject with the following properties:
|
Examples:
// 1. Draw a translucent ellipse on the surface with a checkerboard pattern
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')
})
}));
// 2. Draw different instances each with a unique color
var rectangleInstance = new Cesium.GeometryInstance({
geometry : new Cesium.RectangleGeometry({
rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0),
vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
}),
id : 'rectangle',
attributes : {
color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5)
}
});
var ellipsoidInstance = new Cesium.GeometryInstance({
geometry : new Cesium.EllipsoidGeometry({
radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0),
vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL
}),
modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()),
id : 'ellipsoid',
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
}
});
scene.primitives.add(new Cesium.Primitive({
geometryInstances : [rectangleInstance, ellipsoidInstance],
appearance : new Cesium.PerInstanceColorAppearance()
}));
// 3. Create the geometry on the main thread.
scene.primitives.add(new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : Cesium.EllipsoidGeometry.createGeometry(new Cesium.EllipsoidGeometry({
radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0),
vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL
})),
modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()),
id : 'ellipsoid',
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
}
}),
appearance : new Cesium.PerInstanceColorAppearance()
}));
See:
1.1 Members:
1.2 Methods:
1.3 示例:
通过两种方式添加模型:
1)通过entity方式添加:
// entity方式添加
var entity = viewer.entities.add({
//创建矩形
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
// 西边经度
89.5,
// 南边维度
30,
// 东边经度
110.4,
// 北边维度
40
),
material: Cesium.Color.RED.withAlpha(0.5),
},
});
2)通过primitive方式添加:
// primivite创建矩形
// 01-创建几何体
let rectGeometry = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(
// 西边的经度
115,
// 南边维度
20,
// 东边经度
135,
// 北边维度
30
),
// 距离表面高度
height: 0,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
});
// 02-创建几何体实例
let instance = new Cesium.GeometryInstance({
geometry: rectGeometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
Cesium.Color.RED.withAlpha(0.5)
),
},
});
// 03-设置外观
let appearance = new Cesium.PerInstanceColorAppearance({
flat: true,
});
// 04-图元
let primitive = new Cesium.Primitive({
geometryInstances: instance,
appearance: appearance,
});
// 05-添加到viewer
viewer.scene.primitives.add(primitive);
viewer.camera.setView(viewer.entities);
实现效果:
上面盒子为entity方式创建,下面为primitive方式创建
3)使用primitive添加多个盒子
// primitive方式添加
var instance = new Cesium.GeometryInstance({
//创建矩形几何体
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(
// 西边经度
89.5,
// 南边维度
10,
// 东边经度
110.4,
// 北边维度
20
),
height: 1000,//高度
// vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,//椭球体表面顶点格式化(默认)
}),
// attributes: {
// color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED),
// },
});
const instance2 = new Cesium.GeometryInstance({
//创建圆几何体
geometry: new Cesium.CircleGeometry({
center: Cesium.Cartesian3.fromDegrees(110.4, 40, 0),
radius: 1000000,//半径
// vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
}),
});
var primitiveRect = new Cesium.Primitive({
geometryInstances: [instance, instance2],
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: Cesium.Material.fromType("Color", {
color: Cesium.Color.RED.withAlpha(0.5),
}),
}),
});
viewer.scene.primitives.add(primitiveRect);
实现效果:
上方矩形为entity方式创建,下方矩形和圆形为primitive方式创建:
2. 着色器材质
在上面对primitiveRect进行实例化时,可以通过appearance对多个图元的材质进行设置,例如设置为红色,0.5透明度:
var primitiveRect = new Cesium.Primitive({
geometryInstances: [instance, instance2],
appearance: new Cesium.EllipsoidSurfaceAppearance({//设置同意材质颜色
material: Cesium.Material.fromType("Color", {
color: Cesium.Color.RED.withAlpha(0.5),
}),
}),
});
在对实例进行创建时,也可以通过attributes单独进行设置图元的材质,例如:
// primitive
var instance = new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(
// 西边经度
89.5,
// 南边维度
10,
// 东边经度
110.4,
// 北边维度
20
),
height: 1000,
// vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,//设置顶点格式化
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
Cesium.Color.SKYBLUE
),
},
});
const instance2 = new Cesium.GeometryInstance({
geometry: new Cesium.CircleGeometry({
center: Cesium.Cartesian3.fromDegrees(110.4, 40, 0),
radius: 1000000,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
}),
attributes: {
color: new Cesium.ColorGeometryInstanceAttribute(1, 1, 0, 0.5),
},
id: "circle",
});
在进行实例化时,使用PerInstanceColorAppearance()设置单独的图元材质:
var primitive = new Cesium.Primitive({
geometryInstances: [instance, instance2],
appearance: new Cesium.PerInstanceColorAppearance(),//设置使用自己设置的材质颜色
});
实现效果:
3.创建图元点击交互事件
通过实例化用户输入事件,自定义鼠标左键点击事件,实现对圆图元材质的更改:
// 创建一个交互事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
var pickedObject = viewer.scene.pick(movement.position);
console.log(pickedObject);
console.log(Cesium.defined(pickedObject));
if (Cesium.defined(pickedObject)) {
console.log(pickedObject);
var attributes =
pickedObject.primitive.getGeometryInstanceAttributes("circle");//获取几何体属性
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
Cesium.Color.GREEN.withAlpha(0.5)
);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
点击前:
点击后:
4.通过着色器更改图元颜色
4.1 MaterialAppearance
new Cesium.MaterialAppearance ( options )
Example:
var primitive = new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.WallGeometry({
materialSupport : Cesium.MaterialAppearance.MaterialSupport.BASIC.vertexFormat,
// ...
})
}),
appearance : new Cesium.MaterialAppearance({
material : Cesium.Material.fromType('Color'),
faceForward : true
})
});
4.2 片段着色器fragmentShaderSource
fragmentShaderSource : String
片段着色器的GLSL源代码。完整片段着色器源代码是根据程序
MaterialAppearance#material
而构建的,
MaterialAppearance#flat
和
MaterialAppearance#faceForward
。使用
MaterialAppearance#getFragmentShaderSource
获取完整的源代码。
material :
Material
Scene/MaterialAppearance.js 69
用于确定片段颜色的材料。与其他
MaterialAppearance
不同属性,它不是只读的,因此外观的材质可以随时更改。
Default Value:
Material.ColorType
See:
4.3 片段着色器示例代码:
<template>
<div id="cesiumContainer" ref="cesiumContainer"></div>
</template>
<script setup>
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
import * as dat from "dat.gui";
// console.log(flightData);
const gui = new dat.GUI();
// 设置cesium的token
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";
// cesium默认资源路径
window.CESIUM_BASE_URL = "/";
// 设置默认的视角为中国
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
// 西边经度
89.5,
// 南边维度
0.4,
// 东边经度
110.4,
// 北边维度
81.2
);
onMounted(() => {
var viewer = new Cesium.Viewer("cesiumContainer", {});
viewer.scene.globe.enableLighting = true;
// 设置沙箱允许使用JS
var iframe = document.getElementsByClassName("cesium-infoBox-iframe")[0];
iframe.setAttribute(
"sandbox",
"allow-same-origin allow-scripts allow-popups allow-forms"
);
iframe.setAttribute("src", "");
// // 隐藏cesiumLogo
viewer.cesiumWidget.creditContainer.style.display = "none";
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(112.417, 23.29, 100000),
});//设置初始视角
//挤出一个矩形盒子
const extrudePolygon = new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray([
112.417, 23.29, 113.67, 23.56, 114.093, 22.59, 112.838, 22.285,
])//设置多边形四个点
),
extrudedHeight: 30000,//挤出高度
});
//实例化盒子
const instance = new Cesium.GeometryInstance({
geometry: extrudePolygon,
id: "挤出四边形",
});
//设置材质
const material = new Cesium.Material({
fabric: {
// type: "Color",
// uniforms: {
// color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),//红色0.5透明度
// },
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = vec3(0.84,0.66,0.81);//设置颜色
return material;
}
`,
},
});
console.log(material.shaderSource);//material中的source内容
// const appearance = new Cesium.MaterialAppearance({
// material: material,
// // translucent: true,
// // closed: true,
// });
const appearance = new Cesium.MaterialAppearance({
fragmentShaderSource: `
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
void main()
{
vec3 positionToEyeEC = -v_positionEC;
vec3 normalEC = normalize(v_normalEC);
#ifdef FACE_FORWARD
normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);
#endif
czm_materialInput materialInput;
materialInput.normalEC = normalEC;
materialInput.positionToEyeEC = positionToEyeEC;
materialInput.st = v_st;
czm_material material = czm_getMaterial(materialInput);
material.diffuse = vec3(v_st,0.81);//渐变色
// material.emission = vec3(0.5,0.5,0.5);//发光
// material.specular = 1.0;
material.specular = 1.0;//高光(为1.0时有镜面反射效果)
material.alpha = 1.0;//透明度
#ifdef FLAT
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
#else
gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);
#endif
}
`,
});
// 创建图元添加
var primitive = viewer.scene.primitives.add(
new Cesium.Primitive({
geometryInstances: [instance],
appearance: appearance,
})
);
console.log(appearance.vertexShaderSource);//输出顶点着色器
console.log(appearance.fragmentShaderSource);//输出片元着色器
// let fs = appearance.getFragmentShaderSource();
// console.log(fs);
});
</script>
<style>
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100vw;
height: 100vh;
}
</style>
实现效果: