0

我在我的 WebGL 项目中使用 GLSL 着色器,最近的 Chrome 更新使我的着色器无法链接而没有错误消息。当我在片段着色器中使用制服作为“如果”的条件时,就会出现问题,如下例所示:

uniform int hasTexture;

void main(void) {
    if(hasTexture == 1) {
        // some code
    }
}

在顶点着色器中,它可以工作,如果我在这里不使用制服,它也可以工作。

编辑:这是我的问题发生的完整着色器:

顶点着色器:

attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aVertexTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform mat4 uMVMatrixCenter;

uniform vec3 uSunPosition;
uniform int hasTexture;

uniform int hasNormal;

varying float vLightLength;
varying float vSpecularLength;
varying vec2 vTextureCoord;

uniform float shininess;

uniform float sunPower;

void main(void) {

    vec4 inposition = uMVMatrix * vec4(aVertexPosition, 1.0);

    gl_Position = uPMatrix * inposition;


    if(hasNormal == 1) {

        vec4 transformedLocation = (uMVMatrixCenter * vec4(uSunPosition, 1.0));
        vec3 sunPosition = transformedLocation.xyz;

        vec3 lightDirection = normalize(sunPosition - inposition.xyz);

        vec3 transformedNormal = uNMatrix * aVertexNormal;

        vec3 normal = normalize(transformedNormal);
        vLightLength = max(dot(normal, lightDirection), 0.0)*sunPower;



        vec3 eyeDirection = normalize(-inposition.xyz);
        vec3 reflectionDirection = reflect(-lightDirection, normal);


        vSpecularLength = pow(max(dot(reflectionDirection, eyeDirection), 0.0), 32.0)*sunPower;

    }
    else {
        vLightLength = 1.0;
        vSpecularLength = 0.0;
    }

    if(hasTexture == 1)
        vTextureCoord = aVertexTextureCoord;

}

这是片段着色器:

#ifdef GL_ES
precision highp float;
#endif

varying float vLightLength;
varying float vSpecularLength;
varying vec2 vTextureCoord;

uniform sampler2D uSampler;
uniform int hasTexture;


uniform float ambiantIntensity;
uniform vec3 diffuseColor;
uniform vec3 emissiveColor;
uniform vec3 specularColor;
uniform float shininess;
uniform float transparency;

void main(void) {

    if(hasTexture == 1) {
        gl_FragColor = vec4(texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)).rgb*(
            emissiveColor*(1.0-vLightLength)
            +diffuseColor*vLightLength
            +specularColor*vSpecularLength*shininess), 1.0-transparency); // *vLightLength
    }
    else {
        gl_FragColor = vec4((emissiveColor*(1.0-vLightLength)
                            +diffuseColor*vLightLength
                            +specularColor*vSpecularLength*shininess), 1.0-transparency);
    }
}

这是编译它们的代码:

for(i=0;i<shaderNames.length;i++) {
    vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, shaderSourceList[i*2]);
    gl.compileShader(vertexShader);


    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(vertexShader));
        return;
    }

    fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, shaderSourceList[i*2+1]);
    gl.compileShader(fragmentShader);

    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(fragmentShader));
        return;
    }

    shaderPrograms[i] = gl.createProgram();
    gl.attachShader(shaderPrograms[i], vertexShader);
    gl.attachShader(shaderPrograms[i], fragmentShader);
    gl.linkProgram(shaderPrograms[i]);

    if (!gl.getProgramParameter(shaderPrograms[i], gl.LINK_STATUS)) {
        alert("Could not initialise shader "+shaderNames[i]);
        return;
    }
}

此处返回的错误是“无法初始化着色器”,后跟名称。

如果我从我的代码中删除“if(hasTexture == 1) {”,它就可以工作。

编辑 2:我已经安装了 WebGL 检查器,现在我有一个关于这个缓冲区的错误消息:

“顶点和片段着色器之间的统一 hasTexture 的精度不匹配”

但我不知道我的制服出了什么问题。

4

1 回答 1

0

好的,显然问题是由于顶点和片段着色器中使用了相同的制服,如果我在顶点着色器中将“hasTexture”制服重命名为“hasTextureVS”,它可以工作!

我不知道为什么自从最近的 Chrome 更新以来,现在禁止在两个着色器中使用相同的制服,但这个解决方法解决了我的问题。

于 2013-09-22T19:42:12.730 回答