解决Cesium开发中遇到Compile log: ERROR: 0:3: 'varying': Illegal use of reserved word问题

本篇记录了我在使用Cesium.SkyBox源码更换天空盒图片时,却遇到 Fragment 着色器编译失败的问题。 问题:已解决。

来源

如图所示,这个错误导致了我程序渲染停止了,而且报出提示:

编译日志:ERROR: 0:3: 'varying':非法使用保留字。

排查

我之前有一篇文章记录(解决 Cesium(版本 1.99.0 )开发中遇到 ERROR: 0:1: 'in' : storage qualifier supported in GLS):

该文描述了我使用 Cesium(版本 1.99.0),编辑 GLSL(版本 3.0)代码时遇到的错误,这和我现在遇到的问题其实是一个方向,都是使用的 GLSL 版本的语法不兼容的问题。

之所以这么肯定是,因为我看到CesiumJS官方更新日志:

如图所示,有几点必须标注出来:

  1. CesiumJS在版本 1.102 以后默认使用 WebGL2 上下文进行渲染
  2. 为了在 WebGL2 上下文中工作,任何自定义材质、自定义基元或自定义着色器都需要升级以使用 GLSL 300
  3. 可以通过Cesium.FeatureDetection.supportsWebgl2来检测当前浏览器中是否存在 WebGL2 呈现上下文
  4. 可以设置ContextOptions.requestWebgl1true, 回退到 WebGL1 版本

查验

为了查证,当前版本的CesiumJs是不是使用 WebGL2 上下文渲染的,我通过 APICesium.FeatureDetection.supportsWebgl2(viewer.scene)来测试:

如图所示,的确当前版本的CesiumJs的确使用 WebGL2 上下文渲染,从而任何自定义材质、自定义基元或自定义着色器都需要升级以使用 GLSL 300,而 GLSL3.0 与 2.0 差异中就是有:

jsx 复制代码
用 in 和 out 取代 attribute 和 varying

解难

于是乎,我排查出原因后,后面的操作就很简单了,有两种方式。

  1. 设置ContextOptions.requestWebgl1true, 回退到 WebGL1 版本,使用 GLSL 2.0 的代码
jsx 复制代码
const options: Viewer.ConstructorOptions = {
  infoBox: false,
  selectionIndicator: false,
  shadows: true,
  shouldAnimate: true,
  contextOptions: {
    requestWebgl1: false,
  },
};

export const viewer = new Viewer("cesium-container", options);
jsx 复制代码
// 片元着色器
uniform samplerCube u_cubeMap;

varying vec3 v_texCoord;

void main() {
  vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));
  gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);
}
jsx 复制代码
// 顶点着色器
uniform mat3 u_rotateMatrix;
attribute vec3 position;
varying vec3 v_texCoord;

void main() {
  vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));
  gl_Position = czm_projection * vec4(p, 1.0);
  v_texCoord = position.xyz;
}
  1. 将 GLSL 2.0 代码修改升级为 GLSL3.0 的,完美展示 WebGL2 的渲染效果
jsx 复制代码
// 片元着色器
in vec3 v_texCoord;
void main()
{
  vec4 color = texture(u_cubeMap, normalize(v_texCoord));
  out_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);
}
jsx 复制代码
// 顶点着色器
uniform mat3 u_rotateMatrix;
in vec3 position;
out vec3 v_texCoord;
void main()
{
  vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));
  gl_Position = czm_projection * vec4(p, 1.0);
  v_texCoord = position.xyz;
}

使用

后面,根据思路重新整合,完美解决当前这个问题,效果如下:

结论

看来Cesium1.99.0 和 1.102 版本之前,所使用的 GLSL 代码版本是不一样的,才导致文章提到的这个问题:

相关资料

相关推荐
sunny_19 小时前
⚡️ vite-plugin-oxc:从 Babel 到 Oxc,我为 Vite 写了一个高性能编译插件
前端·webpack·架构
GIS之路19 小时前
ArcPy 开发环境搭建
前端
林小帅21 小时前
【笔记】OpenClaw 架构浅析
前端·agent
林小帅21 小时前
【笔记】OpenClaw 生态系统的多语言实现对比分析
前端·agent
程序猿的程21 小时前
开源一个 React 股票 K 线图组件,传个股票代码就能画图
前端·javascript
不爱说话郭德纲1 天前
告别漫长的HbuilderX云打包排队!uni-app x 安卓本地打包保姆级教程(附白屏、包体积过大排坑指南)
android·前端·uni-app
大雨还洅下1 天前
前端JS: 虚拟dom是什么? 原理? 优缺点?
javascript
唐叔在学习1 天前
[前端特效] 左滑显示按钮的实现介绍
前端·javascript
用户5282290301801 天前
【学习笔记】ECMAScript 词法环境全解析
前端
青青家的小灰灰1 天前
React 架构进阶:自定义 Hooks 的高级设计模式与最佳实践
前端·react.js·前端框架