【问题标题】:Could not initialise shaders after properly compiled正确编译后无法初始化着色器
【发布时间】:2023-03-29 06:00:01
【问题描述】:

谁能帮我解决这个问题?

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

当我添加 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);
} 

【问题讨论】:

  • 您没有显示设置源代码、编译、创建程序、附加着色器和链接的代码,您应该使用gl.getProgramInfoLog(program) 来查看链接错误。

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


【解决方案1】:

您需要致电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 设置为您想要的颜色
  • gl.disableVertexAttribArray(vColourAttribLocation) 关闭vColourAttribute 的属性,然后用gl.vertexAttrib4fv(vColourAttribLocation, [1, 1, 1, 1]) 将其设置为1;
  • uSampler 设置为 1x1 像素的白色纹理

用顶点颜色绘制

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

使用纹理绘制

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

这还可以让您组合诸如通过设置纹理和 uColourMapColour 以及混合顶点颜色和纹理颜色等来绘制着色纹理等内容。

【讨论】:

  • 是的,来自gl.getProgramInfoLog 的消息说您的统一精度与hasTexture 不匹配。
  • 在顶点着色器中int 的默认值为highp,在片段着色器中为mediump。将片段着色器更改为uniform highp int hasTexture 或将顶点着色器更改为uniform mediump int hasTexture
猜你喜欢
  • 2012-07-08
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多