正确编译后无法初始化着色器

时间:2016-08-31 06:21:51

标签: webgl coordinates shader fragment-shader vertex-shader

有人可以帮我吗?

成功编译着色器后,链接状态仍为false。

添加gl.getShaderInfoLog(fragmentShader)时,控制台中没有显示任何内容。

if (type == 'x-fragment') {
str = "#ifdef GL_ES\n" +
"precision highp float;\n" +
"#endif\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D uSampler;\n" +
"uniform int uDrawColourMap;\n" +
"uniform int hasTexture;\n" +
"uniform vec4 uColourMapColour;\n" +
"varying vec4 vColourAttribute;\n" +
"void main(void) {\n" +
"if (uDrawColourMap == 1) {\n" +
"  gl_FragColor = uColourMapColour;\n" +
"  return;\n" +
"}\n" +
"if (hasTexture == 1) {\n" +
"    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n" +
"}\n" +
" else {\n" +
" gl_FragColor = vColourAttribute;\n" +
"}\n" +
"}\n";
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == 'x-vertex') {
str = "attribute vec3 aVertexPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"attribute vec4 aColourAttribute;\n" +
"uniform mat4 uMVMatrix;\n" +
"uniform int hasTexture;\n" +
"uniform mat4 uPMatrix;\n" +
"varying vec4 vColourAttribute;\n" +
"varying vec2 vTextureCoord;\n" +
"void main(void) {\n" +
"    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n" +
" if (hasTexture == 1) {\n"+
" vTextureCoord = aTextureCoord;\n"+
"}\n"+
" else {\n"+
"vColourAttribute = aColourAttribute;\n"+
"}\n"+
"}\n";
shader = gl.createShader(gl.VERTEX_SHADER);
} 

1 个答案:

答案 0 :(得分:0)

您需要致电gl.shaderSource(shader, source)上传您的GLSL来源。然后,您需要调用gl.compileShader(shader)来编译着色器。之后,您可以致电gl.getShaderParameter(shader, gl.COMPILE_SHADER)查看是否成功。此外,在编译着色器后,您可以调用gl.getShaderInfoLog(shader)从GPU驱动程序/浏览器获取任何消息。

注意:根据OpenGL规范,只要着色器无效,它们就可以声称成功编译,但只要它们仍然无法链接。

这意味着您应始终将着色器链接到程序中并检查程序的LINK_STATUS和程序信息日志

var program = gl.createProgram();
gl.attachShader(program, vShaderInfo.shader);
gl.attachShader(program, fShaderInfo.shader);
gl.linkProgram(program);
console.log("link success:", gl.getProgramParameter(program, gl.LINK_STATUS));  
console.log("log:", gl.getProgramInfoLog(program));

您需要致电gl.getProgramInfoLog 而不是 gl.getShaderInfoLog才能从链接中获取错误。

运行以查看错误



var gl = document.createElement("canvas").getContext("webgl");

function makeShader(type) {
if (type == 'x-fragment') {
str = "#ifdef GL_ES\n" +
"precision highp float;\n" +
"#endif\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D uSampler;\n" +
"uniform int uDrawColourMap;\n" +
"uniform int hasTexture;\n" +
"uniform vec4 uColourMapColour;\n" +
"varying vec4 vColourAttribute;\n" +
"void main(void) {\n" +
"if (uDrawColourMap == 1) {\n" +
"  gl_FragColor = uColourMapColour;\n" +
"  return;\n" +
"}\n" +
"if (hasTexture == 1) {\n" +
"    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n" +
"}\n" +
" else {\n" +
" gl_FragColor = vColourAttribute;\n" +
"}\n" +
"}\n";
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == 'x-vertex') {
str = "attribute vec3 aVertexPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"attribute vec4 aColourAttribute;\n" +
"uniform mat4 uMVMatrix;\n" +
"uniform int hasTexture;\n" +
"uniform mat4 uPMatrix;\n" +
"varying vec4 vColourAttribute;\n" +
"varying vec2 vTextureCoord;\n" +
"void main(void) {\n" +
"    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n" +
" if (hasTexture == 1) {\n"+
" vTextureCoord = aTextureCoord;\n"+
"}\n"+
" else {\n"+
"vColourAttribute = aColourAttribute;\n"+
"}\n"+
"}\n";
shader = gl.createShader(gl.VERTEX_SHADER);
} 
return { shader: shader, src: str };
};

function compileShader(shaderInfo) {
 var shader = shaderInfo.shader;
 var src = shaderInfo.src;
  
 gl.shaderSource(shader, src);
 gl.compileShader(shader);
 console.log("compile success:", gl.getShaderParameter(shader, gl.COMPILE_STATUS));  
 console.log("log:", gl.getShaderInfoLog(shader));
}

var vShaderInfo = makeShader('x-fragment');
var fShaderInfo = makeShader('x-vertex');
compileShader(vShaderInfo);
compileShader(fShaderInfo);

var program = gl.createProgram();
gl.attachShader(program, vShaderInfo.shader);
gl.attachShader(program, fShaderInfo.shader);
gl.linkProgram(program);
console.log("link success:", gl.getProgramParameter(program, gl.LINK_STATUS));  
console.log("log:", gl.getProgramInfoLog(program));




上述程序的错误表明hasTexture的统一精度与顶点着色器和片段着色器不匹配。 int的默认值在顶点着色器中为highp,在片段着色器中为mediump,因此请更改其中一个。要么

uniform mediump int hasTexture;

在您的顶点着色器或

uniform highp int hasTexture;

在片段着色器中

或改为布尔。

注意:我觉得有必要指出使用标志来选择着色器中的要素是一种反模式。您应该考虑使用不同的着色器,如果一个着色器中的标志(最好),或者您应该至少删除标记并设计着色器,以便您可以传入白色。

示例:

gl_FragColor = uColourMapColour * 
               texture2D(uSampler, vTextureCoord) *
               vColourAttribute;

用纯色绘制

  • uColourMapColour设置为您想要的颜色
  • 使用vColourAttribute关闭gl.disableVertexAttribArray(vColourAttribLocation)的属性,然后使用gl.vertexAttrib4fv(vColourAttribLocation, [1, 1, 1, 1])将其设置为1;
  • uSampler设置为1x1像素的白色纹理

使用顶点颜色绘制

  • uColourMapColour设为[1,1,1,1])
  • 使用vColourAttribute启用gl.enableVertexAttribArray(vColourAttribLocation)的属性,并将其指向某些数据(gl.bindBuffergl.vertexAttribPointer);
  • uSampler设置为1x1像素的白色纹理

使用纹理绘制

  • uColourMapColour设为[1,1,1,1])
  • 使用vColourAttribute关闭gl.disableVertexAttribArray(vColourAttribLocation)的属性,然后使用gl.vertexAttrib4fv(vColourAttribLocation, [1, 1, 1, 1])将其设置为1;
  • uSampler设置为纹理

这也可以让你通过设置纹理和uColourMapColour来绘制纹理,以及混合顶点颜色和纹理颜色等等。