سؤال

I'm using GLSL shaders in my WebGL project, a recent Chrome update made my shaders not linking without error message. The problem occur when i use a uniform as a condition of a "if" in a fragment shader, like this example :

uniform int hasTexture;

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

In the vertex shader, it works, and if i don't use an uniform here, it works too.

EDIT : Here is the full shader where my problem occur :

Vertex Shader :

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;

}

And here is the fragment shader :

#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);
    }
}

And here is the code compiling them :

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;
    }
}

The error returned here is "Could not initialise shader " followed by the name.

If i remove the "if(hasTexture == 1) {" from my code, it works.

EDIT 2 : I have installed WebGL inspector and i have now an error message for this buffer :

"Precisions for uniform hasTexture do not match between the vertex and fragment shader"

But i don't know what is wrong with my uniform.

هل كانت مفيدة؟

المحلول

Ok, apparently the problem is due to a same uniform used in both vertex and fragment shader, if i rename the "hasTexture" uniform to "hasTextureVS" in the vertex shader, it works !

I don't know why using the same uniform in both shaders is now forbidden since a recent Chrome update, but this workaround solve my problem.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top