WebGL problema de la creación de sombreado
-
28-09-2019 - |
Pregunta
Estoy tratando de hacer una sencilla aplicación en WebGL y JavaScript, y mientras el barbecho algunos tutoriales que he encontrado en internet, me encontré con un problema extraño mientras que la creación de algunos shaders básicos. La función que crea la apariencia de programas de sombreado de la siguiente manera:
this.CreateShaderProgram = function(vertexShader, fragmentShader)
{
var tmp = this.gl.createProgram();
var tempVert = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(tempVert, vertexShader);
this.gl.compileShader(tempVert);
if(!this.gl.getShaderParameter(tempVert, this.gl.COMPILE_STATUS)) {
this.Log("invalid shader : " + vertexShader);
return null;
};
var tempFrag = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(tempFrag, fragmentShader);
this.gl.compileShader(tempFrag);
if(!this.gl.getShaderParameter(tempFrag, this.gl.COMPILE_STATUS)) {
this.Log("invalid shader : " + fragmentShader);
return null;
};
this.gl.attachShader(tmp, tempVert);
this.gl.attachShader(tmp, tempFrag);
return tmp;
}
y los 2 shaders se ven como:
attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
--------------------------------------------
#ifdef GL_ES precision highp float;
#endif
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); };
Lo más curioso es que la primera Vertex Shader compila correctamente, pero para el fragment shader se estrella en el "this.gl.compileShader (tempFrag);" la línea y no puedo entender por qué.
Solución
Este fragmento de código:
#ifdef GL_ES precision highp float;
#endif
En caso de estar en líneas separadas:
#ifdef GL_ES
precision highp float;
#endif
Esto es porque el lenguaje de sombreado utiliza un preprocesador, al igual que el C preprocesador . líneas que comienzan con #
son las directivas de preprocesador, que abarcan toda la línea. Mientras que la declaración precision
no lo es; es sólo una declaración de lo normal en GLSL. Poniéndolos en la misma línea confunde el preprocesador, ya que considera que la declaración de precisión como parte de su directiva.
El consejo de Zecc al uso getShaderInfoLog
también es muy buena para depurar este tipo de problemas.
Otros consejos
Si usted no sabe por qué no es la compilación, a continuación, cambiar el código de la siguiente manera:
this.gl.compileShader(tempFrag);
if(!this.gl.getShaderParameter(tempFrag, this.gl.COMPILE_STATUS)) {
this.Log("invalid shader : " + this.gl.getShaderInfoLog(tempFrag));
return null;
};
Esto debería dar más información sobre lo que está mal (posiblemente el uso de #ifdef
)