Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] Fragment shader compile log: ERROR: 0:8: ‘texture2D‘

04-11 阅读 0评论

Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] Fragment shader compile log: ERROR: 0:8: 'texture2D'

    • 报错原因
    • 解决方法
    • 完整代码
    • 在线示例

      2023年4月19日更新—搞了一个 Cesium 镜像,欢迎使用:沙盒示例 和 API

      在看到 Cesium 官方更新的日志,最新版(1.103.0)支持平滑缩放,于是升级尝试一下。

      结果偶然发现,之前写的墙体动态效果报错,经过调试,找到原因,Cesium 新版对 WebGL2 支持有变化,这里记录一下。

      本文包括,报错原因、解决方法、在线示例三部分。


      报错原因

      报错原因:Cesium 自 1.102.0 开始,为了更好支持跨平台,尤其是移动端,Cesium 默认使用 WebGL2 上下文,如果想使用 WebGL1 上下文,需要在地球初始化的时候设置相应的参数。

      为了在 WebGL2 上下文中工作,任何自定义材质、自定义图元和自定义着色器都需要升级到使用 GLSL 300。

      详见解释:

      openGL之API学习(三十五)texture和texture2D

      The OpenGL® Shading Language

      而笔者写的自定义材质,使用的语法应该是低于 GLSL 300,因此不支持,将语法更新即可。

      涉及语法:

      vec4 colorImage = texture2D(image, vec2(fract(st.t - time), st.t));
      

      官方更新说明。


      Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] Fragment shader compile log: ERROR: 0:8: ‘texture2D‘

      完整错误:

      [Cesium WebGL] Fragment shader compile log: ERROR: 0:8: 'texture2D' : no matching overloaded function found
      ERROR: 0:8: '=' : dimension mismatch
      ERROR: 0:8: '=' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'
      

      [Cesium WebGL]  Fragment shader source:
      #version 300 es
      #ifdef GL_FRAGMENT_PRECISION_HIGH
          precision highp float;
          precision highp int;
      #else
          precision mediump float;
          precision mediump int;
          #define highp mediump
      #endif
      #define OES_texture_float_linear
      #define OES_texture_float
      #line 0
      layout(location = 0) out vec4 out_FragColor;
      

      CesiumWidget.js:703 An error occurred while rendering.  Rendering has stopped.
      RuntimeError: Fragment shader failed to compile.  Compile log: ERROR: 0:8: 'texture2D' : no matching overloaded function found
      ERROR: 0:8: '=' : dimension mismatch
      ERROR: 0:8: '=' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'
      

      解决方法

      以下是两种方法解决问题,推荐第二种。

      1. 初始化地球时(不推荐),传入参数,使用 WebGL1 上下文

      const viewer = new Viewer("cesiumContainer", {
        // 指定上下文
        contextOptions: {
          requestWebgl1: true,
        },
      });
      

      2. 修正 GLSL 代码(推荐)

      错误代码(texture2D):

      vec4 colorImage = texture2D(image, vec2(fract(st.t - time), st.t));
      

      修正为:

      vec4 colorImage = texture(image, vec2(fract(st.t - time), st.t));
      

      完整代码

      
      
      
          
          
          
          
          
          
          Cesium model adjust
          
          
          
          
              @import url(./Widgets/widgets.css);
              html,
              body,
              #cesiumContainer {
                  width: 100%;
                  height: 100%;
                  margin: 0;
                  padding: 0;
                  overflow: hidden;
              }
          
          
              var _hmt = _hmt || [];
              (function () {
                  var hm = document.createElement("script");
                  hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
                  var s = document.getElementsByTagName("script")[0];
                  s.parentNode.insertBefore(hm, s);
              })();
          
          
              var _hmt = _hmt || [];
              (function() {
                  var hm = document.createElement("script");
                  hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
                  var s = document.getElementsByTagName("script")[0];
                  s.parentNode.insertBefore(hm, s);
              })();
          
      
      
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzVlZmUzZi0xMWRmLTQxZGEtYWQyMS1iMDhmYWM3NDkyZjMiLCJpZCI6MTIzMTAsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1NjA4MzkzNTZ9.ORdbpPmws56kqB_GOcdYo-v38ezBkYUVqjPJiZ73JvA'; // 创建三维球 const viewer = init(); viewer.scene.debugShowFramesPerSecond = true; /** * @description:立体墙效果 * @date:2022-02-12 * @param:viewer * @positions: 墙体底部位置坐标 */ function drawWall(positionsTemp) { // 绘制墙体 viewer.entities.add({ name: "立体墙效果", wall: { positions: Cesium.Cartesian3.fromDegreesArrayHeights([ 118.286419,31.864436,20000.0, 119.386419,31.864436,20000.0, 119.386419,32.864436,20000.0, 118.286419,32.864436,20000.0, 118.286419,31.864436,20000.0, ]), // 设置高度 maximumHeights: new Array(5).fill(10000), minimumHeights: new Array(5).fill(1000), material: new DynamicWallMaterialProperty({ color: new Cesium.Color(1.0, 0.0, 0.0, 0.5), duration: 1000 }), } }); } /** * @description:动态立体墙材质 * @date: 2022-02-11 */ //动态墙材质 function DynamicWallMaterialProperty(options) { // 默认参数设置 this._definitionChanged = new Cesium.Event(); this._color = undefined; this._colorSubscription = undefined; this.color = options.color; this.duration = options.duration; this.trailImage = options.trailImage; this._time = (new Date()).getTime(); } Object.defineProperties(DynamicWallMaterialProperty.prototype, { isConstant: { get: function() { return false; } }, definitionChanged: { get: function() { return this._definitionChanged; } }, color: Cesium.createPropertyDescriptor('color') }); DynamicWallMaterialProperty.prototype.getType = function(time) { return 'DynamicWall'; }; DynamicWallMaterialProperty.prototype.getValue = function(time, result) { if (!Cesium.defined(result)) { result = {}; } result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color); if (this.trailImage) { result.image = this.trailImage; } else { result.image = Cesium.Material.DynamicWallImage; } if (this.duration) { result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration; } viewer.scene.requestRender(); return result; }; DynamicWallMaterialProperty.prototype.equals = function(other) { return this === other || (other instanceof DynamicWallMaterialProperty && Cesium.Property.equals(this._color, other._color)); }; Cesium.DynamicWallMaterialProperty = DynamicWallMaterialProperty; Cesium.Material.DynamicWallType = 'DynamicWall'; Cesium.Material.DynamicWallImage = "http://openlayers.vip/resources/polylineTrailLinkMaterial.png"; Cesium.Material.DynamicWallSource = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ czm_material material = czm_getDefaultMaterial(materialInput);\n\ vec2 st = materialInput.st;\n\ vec4 colorImage = texture(image, vec2(fract(st.t - time), st.t));\n\ vec4 fragColor;\n\ fragColor.rgb = color.rgb / 1.0;\n\ fragColor = czm_gammaCorrect(fragColor);\n\ material.alpha = colorImage.a * color.a;\n\ material.diffuse = color.rgb;\n\ material.emission = fragColor.rgb;\n\ return material;\n\ }"; Cesium.Material._materialCache.addMaterial(Cesium.Material.DynamicWallType, { fabric: { type: Cesium.Material.DynamicWallType, uniforms: { color: new Cesium.Color(1.0, 1.0, 1.0, 1), image: Cesium.Material.DynamicWallImage, time: 0 }, source: Cesium.Material.DynamicWallSource }, translucent: function(material) { return true; } }); drawWall(); viewer.zoomTo(viewer.entities);

      在线示例

      示例中展示了, 三维地图动态墙效果。

      Cesium 沙盒测试

      三维地图动态墙效果

      Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] Fragment shader compile log: ERROR: 0:8: ‘texture2D‘



免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]