当前位置:   article > 正文

03-Cesium自定义着色器完整代码以及注释_cesium着色器

cesium着色器

1. 效果展示

2. 完整代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>自定义着色器完整代码</title>
  8. <!-- 线上 -->
  9. <script src="https://cesium.com/downloads/cesiumjs/releases/1.107.1/Build/Cesium/Cesium.js"></script>
  10. <link href="https://cesium.com/downloads/cesiumjs/releases/1.107.1/Build/Cesium/Widgets/widgets.css" rel="stylesheet" />
  11. <style>
  12. #map {
  13. position: absolute;
  14. width: 100%;
  15. height: 100%;
  16. top: 0;
  17. left: 0;
  18. right: 0;
  19. bottom: 0;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div id="map"></div>
  25. <script>
  26. Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZjZkZDAwZC1mNTFhLTRhOTEtOGExNi00MzRhNGIzMDdlNDQiLCJpZCI6MTA1MTUzLCJpYXQiOjE2NjA4MDg0Njd9.qajeJtc4-kppqfR1--Y2FqCu5r3TE1xYYGnEQhy-JF0'
  27. const viewer = new Cesium.Viewer('map', {
  28. infoBox: false,
  29. shadows: true,
  30. terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY,
  31. terrain: Cesium.Terrain.fromWorldTerrain(),
  32. })
  33. //平面的顶点数据
  34. let points = [110.2, 20.0, 112.2, 20.0, 110.2, 22.0, 112.2, 22.0]
  35. let positions = Cesium.Cartesian3.fromDegreesArray(points)
  36. //顶点对应的纹理坐标数据
  37. let sts = [0, 0, 0, 1, 1, 0, 1, 1]
  38. //顶点卷绕的方式
  39. let positionIndex = [0, 1, 2, 1, 2, 3]
  40. function primitivePlaneShader(options) {
  41. console.log(options, 'options')
  42. let viewer = options.viewer
  43. let vertexShader = v_shader()
  44. let fragShader = f_shader()
  45. let sts = new Uint8Array(options.sts) //纹理数据
  46. let positionIndex = new Uint16Array(options.positionIndex) //顶点索引数据
  47. let tempPosition = []
  48. for (var i = 0; i < options.positions.length; i++) {
  49. tempPosition.push(options.positions[i].x)
  50. tempPosition.push(options.positions[i].y)
  51. tempPosition.push(options.positions[i].z)
  52. }
  53. positions = new Float64Array(tempPosition) //顶点数据
  54. let geometry = createGeometry(positions, sts, positionIndex) //几何体
  55. let appearance = createAppearance(vertexShader, fragShader) //外观
  56. //primitive方式加载
  57. viewer.scene.primitives.add(
  58. new Cesium.Primitive({
  59. geometryInstances: new Cesium.GeometryInstance({
  60. //渲染的几何体
  61. geometry: geometry,
  62. }),
  63. appearance: appearance, //外观
  64. asynchronous: false,
  65. })
  66. )
  67. }
  68. function createAppearance(vertexShader, fragShader) {
  69. return new Cesium.Appearance({
  70. material: new Cesium.Material({
  71. /* 在Cesium中,fabric 是用于创建着色器材质(Shader Material)的对象。
  72. 它允许您定义一种着色器材质类型,并通过uniforms(统一变量)传递外部数据给着色器。 */
  73. fabric: {
  74. /*
  75. uniforms是一个包含统一变量(Uniform)的对象。
  76. 统一变量是一种在着色器程序中定义的全局变量,
  77. 它们的值可以在渲染过程中从CPU(JavaScript代码)传递给GPU(着色器代码)。 */
  78. uniforms: {
  79. speed: 0.1,
  80. },
  81. source: getMS(),
  82. },
  83. }),
  84. translucent: false, //显示不为半透明
  85. renderState: {
  86. blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, //使用Alpha混合功能启用混合
  87. depthTest: { enabled: true }, //深度检测
  88. depthMask: true, //将深度值写入深度缓冲区
  89. },
  90. fragmentShaderSource: fragShader, //片段着色器
  91. vertexShaderSource: vertexShader, //顶点着色器
  92. })
  93. }
  94. //构建几何体
  95. function createGeometry(positions, sts, positionIndex) {
  96. return new Cesium.Geometry({
  97. attributes: {
  98. //几何顶点属性
  99. position: new Cesium.GeometryAttribute({
  100. componentDatatype: Cesium.ComponentDatatype.DOUBLE, //数据类型
  101. componentsPerAttribute: 3, //定义几个为一组
  102. values: positions, //坐标值
  103. }),
  104. st: new Cesium.GeometryAttribute({
  105. componentDatatype: Cesium.ComponentDatatype.FLOAT, //数据类型
  106. componentsPerAttribute: 2, //定义几个为一组
  107. values: sts, //坐标值
  108. }),
  109. },
  110. indices: positionIndex, //顶点索引
  111. primitiveType: Cesium.PrimitiveType.TRIANGLES, //图元类型
  112. boundingSphere: Cesium.BoundingSphere.fromVertices(positions), //包围球
  113. })
  114. }
  115. function v_shader() {
  116. // 这段着色器代码的作用是将顶点变换到裁剪空间,并传递纹理坐标给片段着色器,为后续的光栅化和渲染阶段做准备。
  117. return `
  118. in vec3 position3DHigh;//这是一个输入变量,表示高精度的3D位置。通常情况下,这个变量的值是由CesiumJS引擎在渲染过程中提供的,它表示当前处理的顶点或片段的高精度3D位置。
  119. in vec3 position3DLow;//这也是一个输入变量,表示低精度的3D位置。在CesiumJS中,当高精度3D位置无法完全表示时,这个变量提供额外的信息,以便更准确地确定位置。
  120. in float batchId;//这是一个输入变量,表示批次ID。在CesiumJS中,通常用于将相同类型的几何体分组在一起,以优化渲染性能。
  121. in vec2 st;//这是一个输入变量,表示纹理坐标。
  122. out vec2 v_st; //这是一个输出变量,表示处理后的纹理坐标。
  123. void main() {
  124. // czm_computePosition() //计算模型视图相对眼睛坐标空间中的顶点位置。
  125. //czm_modelViewProjectionRelativeToEye//变换顶点位置到裁剪空间,并将结果保存在position中。
  126. vec4 position = czm_modelViewProjectionRelativeToEye *czm_computePosition();
  127. //将输入变量st赋值给输出变量v_st,这样纹理坐标将在顶点着色器中传递给片段着色器。
  128. v_st = st;
  129. //将经过变换后的顶点位置position赋值给内置变量gl_Position,这样OpenGL将使用这个值来确定顶点在屏幕上的位置。
  130. gl_Position = position;
  131. }
  132. `
  133. }
  134. function f_shader() {
  135. return `
  136. in vec2 v_st;//这是一个输入变量,表示纹理坐标。在片段着色器中,v_st变量将包含插值后的纹理坐标值,这些值在顶点着色器中计算并传递给片段着色器。
  137. //uniform float speed;
  138. void main() {
  139. //这一行将纹理坐标(v_st)转换为范围在[-1, 1]的坐标(position)。在OpenGL中,纹理坐标的范围通常是[0, 1],而转换后的坐标在顶点着色器的插值过程中进行了变换,使其范围变为[-1, 1]。
  140. vec2 position = -1.0 + 2.0 *v_st;
  141. //这行代码调用一个函数getSpeed(),该函数返回一个浮点数,表示速度。
  142. float speed = getSpeed();
  143. //这一行根据帧号(czm_frameNumber)和速度(speed)计算时间(time)。czm_frameNumber是CesiumJS引擎提供的一个内置变量,表示当前渲染帧的序号。
  144. float time= czm_frameNumber *speed;
  145. //计算颜色
  146. float r = abs( cos( position.x * position.y + time / 5.0 ));
  147. float g = abs( sin( position.x * position.y + time / 4.0 ) );
  148. float b = abs( cos( position.x * position.y + time / 3.0 ) );
  149. //并将其赋值给特殊的输出变量out_FragColor,这个变量是CesiumJS中用于存储片段着色器输出颜色的内置变量。
  150. out_FragColor = vec4( r, g, b, 1.0 );
  151. }
  152. `
  153. }
  154. function getMS() {
  155. return `#version 300 es
  156. uniform float speed;
  157. float getSpeed(){
  158. return speed;
  159. }
  160. `
  161. }
  162. var plane = new primitivePlaneShader({
  163. viewer: viewer,
  164. positions: positions,
  165. sts: sts,
  166. positionIndex: positionIndex,
  167. })
  168. viewer.scene.camera.setView({
  169. destination: new Cesium.Cartesian3.fromDegrees(110.2, 20.0, 500000),
  170. })
  171. </script>
  172. </body>
  173. </html>

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/99772
推荐阅读
相关标签
  

闽ICP备14008679号