You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将着色器迁移至OpenGL ES 3.0后程序链接失败,求解决

切换到OpenGL ES 3.0 GLSL后着色器程序链接失败问题

问题概述

切换至OpenGL ES 3.0 GLSL版本后,着色器程序无法完成链接(gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)未通过)。检查单个顶点/片段着色器编译状态均显示成功,且着色器日志为空,但获取到程序链接错误日志如下:

Shader Program compile failed:ERROR: 0:41: 'texture2D' : no matching overloaded function found
ERROR: 0:41: '=' : dimension mismatch
ERROR: 0:41: '=' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'

相关代码

顶点着色器

#version 300 es

  in vec3 aVertexPosition;
  in vec3 aVertexNormal;
  in vec2 aTextureCoord;

  uniform mat4 uMVMatrix;
  uniform mat4 uPMatrix;
  uniform mat3 uNMatrix;
  uniform vec3 uAmbientColor;
  uniform vec3 uLightingDirection;
  uniform vec3 uDirectionalColor;
  uniform bool uUseLighting;

  out vec2 vTextureCoord;
  out vec3 vLightWeighting;

  // Spot
  uniform vec3 u_lightWorldPosition;
  out vec3 v_normal;

  out vec3 v_surfaceToLight;
  out vec3 v_surfaceToView;

  // spot-Shadow
  uniform mat4 u_textureMatrix;
  out vec2 v_texcoord;
  out vec4 v_projectedTexcoord;

  void main(void) {
    // SPOT
    v_normal = mat3(uNMatrix) * aVertexNormal;
    vec3 surfaceWorldPosition = (uNMatrix * aVertexPosition).xyz;
    v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;
    v_surfaceToView = (uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0)).xyz - surfaceWorldPosition;

    // spot shadow
    // Multiply the position by the matrix.
    // vec4 worldPosition = u_world * a_position;
    vec4 worldPosition = vec4(0,0,0,0) * vec4( aVertexPosition, 1.0);

    v_texcoord = aTextureCoord;
    v_projectedTexcoord = u_textureMatrix * worldPosition;


    gl_Position   = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;

    if (!uUseLighting) {
      vLightWeighting = vec3(1.0, 1.0, 1.0);
    }
    else {
      vec3 transformedNormal          = uNMatrix * aVertexNormal;
      float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
      vLightWeighting                 = uAmbientColor + uDirectionalColor * directionalLightWeighting;
    }
  } 

片段着色器

#version 300 es
    precision mediump float;
    precision highp float;
    in vec2 vTextureCoord;
    in vec3 vLightWeighting;
    uniform float textureSamplerAmount[1];
    int MixOperandString = 0;

    uniform sampler2D uSampler;
    uniform sampler2D uSampler1;
    uniform sampler2D uSampler2;
    uniform sampler2D uSampler3;
    uniform sampler2D uSampler4;
    uniform sampler2D uSampler5;
    uniform sampler2D uSampler6;
    uniform sampler2D uSampler7;
    in vec3 v_normal;
  in vec3 v_surfaceToLight;
  in vec3 v_surfaceToView;

  uniform vec4 u_color;
  uniform float u_shininess;
  uniform vec3 u_lightDirection;
  uniform float u_innerLimit;          // in dot space
  uniform float u_outerLimit;          // in dot space

  uniform mat4 u_projection;
  uniform mat4 u_view;
  uniform mat4 u_world;
  uniform mat4 u_textureMatrix;

  out vec4 outColor;

  void main(void) {

        vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
        vec4 textureColor1 = texture2D(uSampler1, vec2(vTextureCoord.s, vTextureCoord.t));
        vec4 textureColor2 = texture2D(uSampler2, vec2(vTextureCoord.s, vTextureCoord.t));
        vec4 textureColor3 = texture2D(uSampler3, vec2(vTextureCoord.s, vTextureCoord.t));
        vec4 textureColor4 = texture2D(uSampler4, vec2(vTextureCoord.s, vTextureCoord.t));

        if (1 == 1) {
          outColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
        } 

   
  vec3 normal = normalize(v_normal);

  vec3 surfaceToLightDirection = normalize(v_surfaceToLight);
  vec3 surfaceToViewDirection = normalize(v_surfaceToView);
  vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);

  float dotFromDirection = dot(surfaceToLightDirection,
                               -u_lightDirection);
  float limitRange = u_innerLimit - u_outerLimit;
  float inLight = clamp((dotFromDirection - u_outerLimit) / limitRange, 0.0, 1.0);
  float light = inLight * dot(normal, surfaceToLightDirection);
  float specular = inLight * pow(dot(normal, halfVector), u_shininess);

  outColor.rgb *= light;
  // Just add in the specular
  // outColor.rgb += specular;
  
  

    }

错误排查代码

var shaderProgram = gl.createProgram();
// console.log("Creating Shader fragment");
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

console.info('TEST ERROR => ' + gl.getShaderInfoLog(vertexShader));
console.info('TEST ERROR => ' + gl.getShaderInfoLog(fragmentShader));

编译状态检查代码及输出

var compiled = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS);
console.log('Shader compiled successfully: ' + compiled);
var compiled = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);
console.log('Shader fragmentShader compiled successfully: ' + compiled);

输出:

Shader compiled successfully: true
app.js:810 Shader fragmentShader compiled successfully: true

问题原因

  1. API函数弃用:GLSL ES 3.0(#version 300 es)中已移除texture2D()函数,统一使用通用的texture()函数替代。原代码中调用不存在的texture2D()导致找不到匹配函数,进而引发后续的维度不匹配、类型转换错误。
  2. 冗余精度声明:片段着色器中重复设置precision mediump float;和precision highp float;,虽不影响链接,但易造成混淆。

解决方案

  1. 替换纹理采样函数:将片段着色器中所有texture2D()调用替换为texture(),示例:
    vec4 textureColor = texture(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    vec4 textureColor1 = texture(uSampler1, vec2(vTextureCoord.s, vTextureCoord.t));
    // 其余textureColor2至textureColor4同理修改
    
  2. 清理冗余精度声明:移除重复的精度设置,保留一个即可,例如保留precision mediump float;(片段着色器常用中等精度)。
  3. 可选代码优化:顶点着色器中vec4 worldPosition = vec4(0,0,0,0) * vec4( aVertexPosition, 1.0);计算结果恒为零向量,属于无效代码,建议根据实际需求修正或删除。

修改验证

完成上述修改后,重新编译并链接着色器程序,gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)应返回true,链接错误日志消失。

内容的提问来源于stack exchange,提问作者Nikola Lukic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:25:54