解决:Both vertex and fragment programs must be present in a CGPROGRAM

在将Unity项目从2018版本升级到2021版本过程中,遇到Shader警告,提示顶点和片段程序都必须存在。经过一系列排查,包括检查语法、CGPROGRAM和ENDCG拼写、特殊Shader语法,最终发现是Shader文件中存在不可见的ASCII换行符(0x0a)。使用Sublime Text打开文件时,发现了这些特殊字符并删除后,问题得到解决。原来是ASCII编码与UTF8编码的差异导致的隐藏问题。

        最近正在做unity项目从2018升级到unity2021版本,某个shader报Shader warnig in "xxxx.shader":Both vertex and fragment programs must be present in a CGPROGRAM. Excluding it from compilation.错误,第一反应是肯定是Shader本省错误。肉眼看去并没有发现有什么错误,也与2018的版本Shader进行比较,并无差异

        奇怪的现象,总是有一些不为人知的隐藏,但往往又无法解释,就此开始一一尝试:

1、怀疑语法错误

        因为我的shader有多个pass,我就一一屏蔽,发现情况依旧,结果失败

2、检查 CGPROGRAM,ENDCG 是否拼写 错误

       仔仔细细检查,结果失败

3、是否用到特殊Shader语法特性

        shader内容相对简单,并没有特殊语义的地方

4、神奇时刻,用subline text 打开

      先前看shader文件都是通过vs打开,阴差阳错我想看下类似的shader与该shader文件有什么不同,通过subline text文本编辑器软件打开该文件,神奇的情况发现了,在#pragma vertex vert 语句后面竟然有一个 特殊转义字符(0x0a)Ascii换行符,并发现其他语句也有,尝试删除该字符

既然成功了,直接破案。

 结论:

        原来的shader是Ascii编码,而 subline Text是utf8编码,所以subline Text能看出来,为啥VS打开时候看不到呢,是因为vs是自适应文件的编码格式,所以用它打开无法看到(0x0a)Ascii换行符

在移动端 H5 人脸识别插件运行过程中,出现 **"Failed to link vertex and fragment shaders"** 的错误通常与着色器代码兼容性、WebGL 上下文配置或运行环境限制有关。以下是可能的解决方案和排查步骤: ### 1. 检查着色器代码语法和兼容性 确保顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)的 GLSL 代码在 WebGL 环境下是兼容的。WebGL 1.0 支持的是 GLSL ES 1.0,而 WebGL 2.0 支持 GLSL ES 3.0。如果着色器使用了不被支持的特性或语法,链接会失败。 例如,确保变量声明、精度限定符、内建变量等符合规范: ```glsl // 顶点着色器示例(WebGL 1.0) attribute vec4 a_position; void main() { gl_Position = a_position; } ``` ```glsl // 片段着色器示例(WebGL 1.0) precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } ``` 确保 `precision` 声明正确,避免未声明精度导致的编译失败[^3]。 ### 2. 检查 WebGL 上下文创建是否成功 在创建 WebGL 渲染上下文时,如果失败会导致着色器无法编译和链接。需要在 JavaScript 中检查上下文是否成功创建: ```javascript const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) { console.error('WebGL context creation failed'); return; } ``` 若无法获取 WebGL 上下文,则后续着色器操作将失败。 ### 3. 检查着色器编译状态和日志 在编译顶点和片段着色器后,应检查其编译状态并输出日志信息,以定位具体错误: ```javascript function compileShader(gl, type, source) { const shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error('Shader compilation failed:', gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; } ``` ### 4. 链接程序前检查着色器是否成功附加 确保在链接程序对象之前,顶点着色器和片段着色器都已成功附加,并且链接后检查链接状态: ```javascript const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error('Program linking failed:', gl.getProgramInfoLog(program)); } ``` ### 5. 移动端浏览器兼容性处理 某些移动端浏览器对 WebGL 的支持存在限制或 bug,尤其是在使用人脸识别插件时,可能涉及额外的摄像头纹理处理。可以尝试以下措施: - **使用回退机制**:检测是否支持 WebGL,若不支持则回退到 2D Canvas 渲染。 - **设置合适的 WebGL 上下文属性**: ```javascript const contextAttributes = { alpha: false, depth: false, stencil: false, antialias: false }; const gl = canvas.getContext('webgl', contextAttributes); ``` - **避免使用高精度变量**:在某些低端设备上,`highp` 精度可能导致编译失败,建议使用 `mediump` 或 `lowp`。 ### 6. 使用调试工具辅助排查 可以借助浏览器的开发者工具(如 Chrome DevTools)查看 WebGL 着色器日志、性能瓶颈和上下文状态。此外,使用 WebGL 调试库如 `webgl-lint` 可帮助发现潜在问题。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值