我在我的 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 的精度不匹配”
但我不知道我的制服出了什么问题。