赞
踩
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>自定义着色器完整代码</title>
- <!-- 线上 -->
- <script src="https://cesium.com/downloads/cesiumjs/releases/1.107.1/Build/Cesium/Cesium.js"></script>
- <link href="https://cesium.com/downloads/cesiumjs/releases/1.107.1/Build/Cesium/Widgets/widgets.css" rel="stylesheet" />
-
- <style>
- #map {
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
- </style>
- </head>
-
- <body>
- <div id="map"></div>
- <script>
- Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZjZkZDAwZC1mNTFhLTRhOTEtOGExNi00MzRhNGIzMDdlNDQiLCJpZCI6MTA1MTUzLCJpYXQiOjE2NjA4MDg0Njd9.qajeJtc4-kppqfR1--Y2FqCu5r3TE1xYYGnEQhy-JF0'
- const viewer = new Cesium.Viewer('map', {
- infoBox: false,
- shadows: true,
- terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY,
- terrain: Cesium.Terrain.fromWorldTerrain(),
- })
-
- //平面的顶点数据
- let points = [110.2, 20.0, 112.2, 20.0, 110.2, 22.0, 112.2, 22.0]
- let positions = Cesium.Cartesian3.fromDegreesArray(points)
- //顶点对应的纹理坐标数据
- let sts = [0, 0, 0, 1, 1, 0, 1, 1]
-
- //顶点卷绕的方式
- let positionIndex = [0, 1, 2, 1, 2, 3]
-
- function primitivePlaneShader(options) {
- console.log(options, 'options')
- let viewer = options.viewer
- let vertexShader = v_shader()
- let fragShader = f_shader()
- let sts = new Uint8Array(options.sts) //纹理数据
- let positionIndex = new Uint16Array(options.positionIndex) //顶点索引数据
- let tempPosition = []
- for (var i = 0; i < options.positions.length; i++) {
- tempPosition.push(options.positions[i].x)
- tempPosition.push(options.positions[i].y)
- tempPosition.push(options.positions[i].z)
- }
- positions = new Float64Array(tempPosition) //顶点数据
- let geometry = createGeometry(positions, sts, positionIndex) //几何体
- let appearance = createAppearance(vertexShader, fragShader) //外观
- //primitive方式加载
- viewer.scene.primitives.add(
- new Cesium.Primitive({
- geometryInstances: new Cesium.GeometryInstance({
- //渲染的几何体
- geometry: geometry,
- }),
- appearance: appearance, //外观
- asynchronous: false,
- })
- )
- }
- function createAppearance(vertexShader, fragShader) {
- return new Cesium.Appearance({
- material: new Cesium.Material({
- /* 在Cesium中,fabric 是用于创建着色器材质(Shader Material)的对象。
- 它允许您定义一种着色器材质类型,并通过uniforms(统一变量)传递外部数据给着色器。 */
- fabric: {
- /*
- uniforms是一个包含统一变量(Uniform)的对象。
- 统一变量是一种在着色器程序中定义的全局变量,
- 它们的值可以在渲染过程中从CPU(JavaScript代码)传递给GPU(着色器代码)。 */
- uniforms: {
- speed: 0.1,
- },
- source: getMS(),
- },
- }),
- translucent: false, //显示不为半透明
- renderState: {
- blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, //使用Alpha混合功能启用混合
- depthTest: { enabled: true }, //深度检测
- depthMask: true, //将深度值写入深度缓冲区
- },
- fragmentShaderSource: fragShader, //片段着色器
- vertexShaderSource: vertexShader, //顶点着色器
- })
- }
- //构建几何体
- function createGeometry(positions, sts, positionIndex) {
- return new Cesium.Geometry({
- attributes: {
- //几何顶点属性
- position: new Cesium.GeometryAttribute({
- componentDatatype: Cesium.ComponentDatatype.DOUBLE, //数据类型
- componentsPerAttribute: 3, //定义几个为一组
- values: positions, //坐标值
- }),
- st: new Cesium.GeometryAttribute({
- componentDatatype: Cesium.ComponentDatatype.FLOAT, //数据类型
- componentsPerAttribute: 2, //定义几个为一组
- values: sts, //坐标值
- }),
- },
- indices: positionIndex, //顶点索引
- primitiveType: Cesium.PrimitiveType.TRIANGLES, //图元类型
- boundingSphere: Cesium.BoundingSphere.fromVertices(positions), //包围球
- })
- }
- function v_shader() {
- // 这段着色器代码的作用是将顶点变换到裁剪空间,并传递纹理坐标给片段着色器,为后续的光栅化和渲染阶段做准备。
- return `
- in vec3 position3DHigh;//这是一个输入变量,表示高精度的3D位置。通常情况下,这个变量的值是由CesiumJS引擎在渲染过程中提供的,它表示当前处理的顶点或片段的高精度3D位置。
- in vec3 position3DLow;//这也是一个输入变量,表示低精度的3D位置。在CesiumJS中,当高精度3D位置无法完全表示时,这个变量提供额外的信息,以便更准确地确定位置。
- in float batchId;//这是一个输入变量,表示批次ID。在CesiumJS中,通常用于将相同类型的几何体分组在一起,以优化渲染性能。
- in vec2 st;//这是一个输入变量,表示纹理坐标。
- out vec2 v_st; //这是一个输出变量,表示处理后的纹理坐标。
- void main() {
- // czm_computePosition() //计算模型视图相对眼睛坐标空间中的顶点位置。
- //czm_modelViewProjectionRelativeToEye//变换顶点位置到裁剪空间,并将结果保存在position中。
- vec4 position = czm_modelViewProjectionRelativeToEye *czm_computePosition();
- //将输入变量st赋值给输出变量v_st,这样纹理坐标将在顶点着色器中传递给片段着色器。
- v_st = st;
- //将经过变换后的顶点位置position赋值给内置变量gl_Position,这样OpenGL将使用这个值来确定顶点在屏幕上的位置。
- gl_Position = position;
- }
- `
- }
-
- function f_shader() {
- return `
- in vec2 v_st;//这是一个输入变量,表示纹理坐标。在片段着色器中,v_st变量将包含插值后的纹理坐标值,这些值在顶点着色器中计算并传递给片段着色器。
- //uniform float speed;
- void main() {
- //这一行将纹理坐标(v_st)转换为范围在[-1, 1]的坐标(position)。在OpenGL中,纹理坐标的范围通常是[0, 1],而转换后的坐标在顶点着色器的插值过程中进行了变换,使其范围变为[-1, 1]。
- vec2 position = -1.0 + 2.0 *v_st;
- //这行代码调用一个函数getSpeed(),该函数返回一个浮点数,表示速度。
- float speed = getSpeed();
- //这一行根据帧号(czm_frameNumber)和速度(speed)计算时间(time)。czm_frameNumber是CesiumJS引擎提供的一个内置变量,表示当前渲染帧的序号。
- float time= czm_frameNumber *speed;
- //计算颜色
- float r = abs( cos( position.x * position.y + time / 5.0 ));
- float g = abs( sin( position.x * position.y + time / 4.0 ) );
- float b = abs( cos( position.x * position.y + time / 3.0 ) );
- //并将其赋值给特殊的输出变量out_FragColor,这个变量是CesiumJS中用于存储片段着色器输出颜色的内置变量。
- out_FragColor = vec4( r, g, b, 1.0 );
- }
- `
- }
-
- function getMS() {
- return `#version 300 es
- uniform float speed;
- float getSpeed(){
- return speed;
- }
- `
- }
-
- var plane = new primitivePlaneShader({
- viewer: viewer,
- positions: positions,
- sts: sts,
- positionIndex: positionIndex,
- })
- viewer.scene.camera.setView({
- destination: new Cesium.Cartesian3.fromDegrees(110.2, 20.0, 500000),
- })
- </script>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。