WebGL 片段着色器构造函数错误 - 参数太多
WebGL Fragment Shader constructor error - Too many arguments
我正在开发一个 Javascript/OpenGL(WebGL) 程序,该程序应该制作一个 3D 立方体,其纹理颜色看起来像魔方。到目前为止,我已经很好地映射了纹理,并且立方体中的每个点似乎都正确显示。
但是,我很难在不从片段着色器中得到一些错误的情况下在其上显示颜色。此刻,我遇到了这个错误,我一直在尝试解决这个错误,但运气不佳。这是错误消息。
Error: fragment shader compiler: ERROR: 0:11: 'constructor' : too many arguments
这是我要具体查看的片段着色器代码。
<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
// extract the RGBA color from image at given coordinates.
vec4 oldColor = texture2D( image0, textureCoordinatesV );
vec4 newColor;
newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
gl_FragColor = newColor;
}
</script>
这是我在这个程序中使用的图像。
http://tinypic.com/view.php?pic=2rpbbqq&s=9#.Vkj3jPmrTIU
这是我的完整代码。我知道 three.js 在 WebGL 中渲染 3D 对象,但目前的方法是让我更好地理解如何使用现有工具渲染对象。此外,如果您在查看立方体时遇到问题,请在 Firefox 中尝试 运行 这个程序。
有一个 Vector4.js 和 Matrix4.js 我正在使用这个程序,但据我所知,它们与我收到的当前错误消息没有任何关系. Vector4 只是一个脚本,它为我建立一个 Vector4 结构,用于保存要渲染的顶点,而 Matrix4 是一个脚本,用于在这些顶点建立后移动它们。如果需要,我会在评论中post这些文件。
如果您能帮助我找出为什么会不断出现此错误,我们将不胜感激,非常感谢。
<html>
<head>
<title>Template WebGL file</title>
</head>
<body onload="main()">
<canvas id="myCanvas" width="400" height="400"></canvas>
<!-- Load external file with helper setup functions. -->
<script src="webgl-utils.js"></script>
<script src="Vector4.js"></script>
<script src="Matrix4.js"></script>
<!-- vertex shader code -->
<script id="vertex-shader" type="x-shader">
attribute vec4 pointPosition;
uniform mat4 transformation;
attribute vec4 pointColorA;
varying vec4 pointColorV;
attribute vec2 textureCoordinatesA;
varying vec2 textureCoordinatesV;
void main()
{
gl_Position = transformation * pointPosition;
textureCoordinatesV = textureCoordinatesA;
pointColorV = pointColorA;
}
</script>
<!-- fragment shader code -->
<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
// extract the RGBA color from image at given coordinates.
vec4 oldColor = texture2D( image0, textureCoordinatesV );
vec4 newColor;
newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
gl_FragColor = newColor;
}
</script>
<!-- main Javascript program -->
<script>
// DECLARE GLOBAL JAVASCRIPT VARIABLES
var canvas = document.getElementById('myCanvas');
var gl; // the WebGL context
var transformationData, transformationAddress;
var x, y, z, angle, scale, time;
function main()
{
// STANDARD STARTUP CODE
gl = setupWebGL(canvas);
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
gl.enable(gl.DEPTH_TEST);
// WRITE MAIN JAVASCRIPT CODE HERE
// [x,y,z, r,g,b]
var v0 = [0,0,0]; // back; black
var v1 = [0,0,1]; // z axis; blue
var v2 = [0,1,0]; // y axis; green
var v3 = [0,1,1]; // y+z; cyan
var v4 = [1,0,0]; // x axis; red
var v5 = [1,0,1]; // x+z; magenta
var v6 = [1,1,0]; // x+y; yellow
var v7 = [1,1,1]; // all; white
var uv0 = [0,0];
var uv1 = [0,1];
var uv2 = [1,0];
var uv3 = [1,1];
var cr = [1,0,0]; //red
var cg = [0,1,0]; //green
var cb = [0,0,1]; //blue
var cy = [1,1,0]; //yellow
var co = [1,0.5,0]; //orange
var cw = [1,1,1]; //white
var data = [];
// left x2, right x2, front x2, back x2, up x2, down x2
data = data.concat( v7,uv3,cr,v3,uv1,cr,v1,uv0,cr, v7,uv3,cr,v1,uv0,cr,v5,uv2,cr, // front
v3,uv3,cy,v2,uv1,cy,v0,uv0,cy, v3,uv3,cy,v0,uv0,cy,v1,uv2,cy, // left
v6,uv3,cb,v2,uv1,cb,v3,uv0,cb, v6,uv3,cb,v3,uv0,cb,v7,uv2,cb, // up
v2,uv3,co,v6,uv1,co,v4,uv0,co, v2,uv3,co,v4,uv0,co,v0,uv2,co, // back
v6,uv3,cw,v7,uv1,cw,v5,uv0,cw, v6,uv3,cw,v5,uv0,cw,v4,uv2,cw, // right
v5,uv3,cg,v1,uv1,cg,v0,uv0,cg, v5,uv3,cg,v0,uv0,cg,v4,uv2,cg, v0 ); // down
var attributeArray = new Float32Array( data );
var attributeBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, attributeBuffer );
gl.bufferData( gl.ARRAY_BUFFER, attributeArray, gl.STATIC_DRAW );
var pointPositionAddress =
gl.getAttribLocation( program, "pointPosition" );
var textureCoordinatesAddress =
gl.getAttribLocation( program, "textureCoordinatesA" );
var pointColorAddress =
gl.getAttribLocation( program, "pointColorA" );
var BPE = attributeArray.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(
pointPositionAddress, 3, gl.FLOAT, false, 8*BPE, 0*BPE );
gl.enableVertexAttribArray( pointPositionAddress );
gl.vertexAttribPointer(
textureCoordinatesAddress, 3, gl.FLOAT, false, 8*BPE, 3*BPE );
gl.enableVertexAttribArray( textureCoordinatesAddress );
gl.vertexAttribPointer(
pointColorAddress, 3, gl.FLOAT, false, 8 * BPE, 4*BPE);
gl.enableVertexAttribArray(pointColorAddress);
transformationAddress = gl.getUniformLocation( program, "transformation" );
transformationData = new Matrix4().setIdentity();
x = 0;
y = 0;
z = 0;
angle = 0;
scale = 1;
time = 0;
// set up texture buffer
var textureBuffer = gl.createTexture();
var imageAddress = gl.getUniformLocation( program, "image0" );
var imageData = new Image();
// when image is done loading run some code (load into GPU)
imageData.onload = function() {
loadTexture0(textureBuffer, imageData, imageAddress); }
// start loading the image
imageData.src = "DDBingoGrid.png";
gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
loop();
}
// OTHER FUNCTIONS
function loadTexture0( tb, id, ia )
{
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture(gl.TEXTURE_2D, tb);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB,
gl.UNSIGNED_BYTE, id);
gl.uniform1i( ia, 0 );
}
function loop()
{
update();
render();
setTimeout( loop, 16 );
}
// update JavaScript variables; send new data to GPU
function update()
{
time += 0.016; // 60 FPS!
x += 0.00;
y += 0.00;
z += 0.00;
angle += 0.01;
scale += 0.00;
var model = new Matrix4();
var t = new Matrix4();
t.setTranslation(-1/2, 0, -1/2);
var rx = new Matrix4();
rx.setRotationX( angle );
var ry = new Matrix4();
ry.setRotationY(angle);
model = rx.multiply(ry).multiply(t);
var camera = new Matrix4();
camera.setTranslation(0,0,6);
var view = camera.inverse();
var projection = new Matrix4();
projection.setPerspective( 45, 1, 0.1, 100 );
transformationData = projection.multiply(view).multiply(model);
gl.uniformMatrix4fv( transformationAddress, false, transformationData.toArray() );
}
// draw all the things
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT );
gl.clear( gl.DEPTH_BUFFER_BIT );
gl.drawArrays( gl.TRIANGLES, 0, 36 );
}
</script>
</body>
</html>
问题出在这一行:
newColor = vec4(oldColor.r * pointColorV,
oldColor.g * pointColorV,
oldColor.b * pointColorV,
1.0);
在 glsl 中,float*vector
操作 returns 向量。由于 pointColorV
是一个向量,您尝试将三个 vec4 对象传递给 vec4 构造函数,这是不可能的。您可以通过在 pointColorV 之后添加正确的调配运算符 .r/.g/.b
来解决该问题。但更好的选择是将整个事情写成一个操作:
newColor = vec4(oldColor.rgb * pointColorV.rgb, 1.0);
我正在开发一个 Javascript/OpenGL(WebGL) 程序,该程序应该制作一个 3D 立方体,其纹理颜色看起来像魔方。到目前为止,我已经很好地映射了纹理,并且立方体中的每个点似乎都正确显示。
但是,我很难在不从片段着色器中得到一些错误的情况下在其上显示颜色。此刻,我遇到了这个错误,我一直在尝试解决这个错误,但运气不佳。这是错误消息。
Error: fragment shader compiler: ERROR: 0:11: 'constructor' : too many arguments
这是我要具体查看的片段着色器代码。
<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
// extract the RGBA color from image at given coordinates.
vec4 oldColor = texture2D( image0, textureCoordinatesV );
vec4 newColor;
newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
gl_FragColor = newColor;
}
</script>
这是我在这个程序中使用的图像。
http://tinypic.com/view.php?pic=2rpbbqq&s=9#.Vkj3jPmrTIU
这是我的完整代码。我知道 three.js 在 WebGL 中渲染 3D 对象,但目前的方法是让我更好地理解如何使用现有工具渲染对象。此外,如果您在查看立方体时遇到问题,请在 Firefox 中尝试 运行 这个程序。
有一个 Vector4.js 和 Matrix4.js 我正在使用这个程序,但据我所知,它们与我收到的当前错误消息没有任何关系. Vector4 只是一个脚本,它为我建立一个 Vector4 结构,用于保存要渲染的顶点,而 Matrix4 是一个脚本,用于在这些顶点建立后移动它们。如果需要,我会在评论中post这些文件。
如果您能帮助我找出为什么会不断出现此错误,我们将不胜感激,非常感谢。
<html>
<head>
<title>Template WebGL file</title>
</head>
<body onload="main()">
<canvas id="myCanvas" width="400" height="400"></canvas>
<!-- Load external file with helper setup functions. -->
<script src="webgl-utils.js"></script>
<script src="Vector4.js"></script>
<script src="Matrix4.js"></script>
<!-- vertex shader code -->
<script id="vertex-shader" type="x-shader">
attribute vec4 pointPosition;
uniform mat4 transformation;
attribute vec4 pointColorA;
varying vec4 pointColorV;
attribute vec2 textureCoordinatesA;
varying vec2 textureCoordinatesV;
void main()
{
gl_Position = transformation * pointPosition;
textureCoordinatesV = textureCoordinatesA;
pointColorV = pointColorA;
}
</script>
<!-- fragment shader code -->
<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
// extract the RGBA color from image at given coordinates.
vec4 oldColor = texture2D( image0, textureCoordinatesV );
vec4 newColor;
newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
gl_FragColor = newColor;
}
</script>
<!-- main Javascript program -->
<script>
// DECLARE GLOBAL JAVASCRIPT VARIABLES
var canvas = document.getElementById('myCanvas');
var gl; // the WebGL context
var transformationData, transformationAddress;
var x, y, z, angle, scale, time;
function main()
{
// STANDARD STARTUP CODE
gl = setupWebGL(canvas);
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
gl.enable(gl.DEPTH_TEST);
// WRITE MAIN JAVASCRIPT CODE HERE
// [x,y,z, r,g,b]
var v0 = [0,0,0]; // back; black
var v1 = [0,0,1]; // z axis; blue
var v2 = [0,1,0]; // y axis; green
var v3 = [0,1,1]; // y+z; cyan
var v4 = [1,0,0]; // x axis; red
var v5 = [1,0,1]; // x+z; magenta
var v6 = [1,1,0]; // x+y; yellow
var v7 = [1,1,1]; // all; white
var uv0 = [0,0];
var uv1 = [0,1];
var uv2 = [1,0];
var uv3 = [1,1];
var cr = [1,0,0]; //red
var cg = [0,1,0]; //green
var cb = [0,0,1]; //blue
var cy = [1,1,0]; //yellow
var co = [1,0.5,0]; //orange
var cw = [1,1,1]; //white
var data = [];
// left x2, right x2, front x2, back x2, up x2, down x2
data = data.concat( v7,uv3,cr,v3,uv1,cr,v1,uv0,cr, v7,uv3,cr,v1,uv0,cr,v5,uv2,cr, // front
v3,uv3,cy,v2,uv1,cy,v0,uv0,cy, v3,uv3,cy,v0,uv0,cy,v1,uv2,cy, // left
v6,uv3,cb,v2,uv1,cb,v3,uv0,cb, v6,uv3,cb,v3,uv0,cb,v7,uv2,cb, // up
v2,uv3,co,v6,uv1,co,v4,uv0,co, v2,uv3,co,v4,uv0,co,v0,uv2,co, // back
v6,uv3,cw,v7,uv1,cw,v5,uv0,cw, v6,uv3,cw,v5,uv0,cw,v4,uv2,cw, // right
v5,uv3,cg,v1,uv1,cg,v0,uv0,cg, v5,uv3,cg,v0,uv0,cg,v4,uv2,cg, v0 ); // down
var attributeArray = new Float32Array( data );
var attributeBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, attributeBuffer );
gl.bufferData( gl.ARRAY_BUFFER, attributeArray, gl.STATIC_DRAW );
var pointPositionAddress =
gl.getAttribLocation( program, "pointPosition" );
var textureCoordinatesAddress =
gl.getAttribLocation( program, "textureCoordinatesA" );
var pointColorAddress =
gl.getAttribLocation( program, "pointColorA" );
var BPE = attributeArray.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(
pointPositionAddress, 3, gl.FLOAT, false, 8*BPE, 0*BPE );
gl.enableVertexAttribArray( pointPositionAddress );
gl.vertexAttribPointer(
textureCoordinatesAddress, 3, gl.FLOAT, false, 8*BPE, 3*BPE );
gl.enableVertexAttribArray( textureCoordinatesAddress );
gl.vertexAttribPointer(
pointColorAddress, 3, gl.FLOAT, false, 8 * BPE, 4*BPE);
gl.enableVertexAttribArray(pointColorAddress);
transformationAddress = gl.getUniformLocation( program, "transformation" );
transformationData = new Matrix4().setIdentity();
x = 0;
y = 0;
z = 0;
angle = 0;
scale = 1;
time = 0;
// set up texture buffer
var textureBuffer = gl.createTexture();
var imageAddress = gl.getUniformLocation( program, "image0" );
var imageData = new Image();
// when image is done loading run some code (load into GPU)
imageData.onload = function() {
loadTexture0(textureBuffer, imageData, imageAddress); }
// start loading the image
imageData.src = "DDBingoGrid.png";
gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
loop();
}
// OTHER FUNCTIONS
function loadTexture0( tb, id, ia )
{
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture(gl.TEXTURE_2D, tb);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB,
gl.UNSIGNED_BYTE, id);
gl.uniform1i( ia, 0 );
}
function loop()
{
update();
render();
setTimeout( loop, 16 );
}
// update JavaScript variables; send new data to GPU
function update()
{
time += 0.016; // 60 FPS!
x += 0.00;
y += 0.00;
z += 0.00;
angle += 0.01;
scale += 0.00;
var model = new Matrix4();
var t = new Matrix4();
t.setTranslation(-1/2, 0, -1/2);
var rx = new Matrix4();
rx.setRotationX( angle );
var ry = new Matrix4();
ry.setRotationY(angle);
model = rx.multiply(ry).multiply(t);
var camera = new Matrix4();
camera.setTranslation(0,0,6);
var view = camera.inverse();
var projection = new Matrix4();
projection.setPerspective( 45, 1, 0.1, 100 );
transformationData = projection.multiply(view).multiply(model);
gl.uniformMatrix4fv( transformationAddress, false, transformationData.toArray() );
}
// draw all the things
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT );
gl.clear( gl.DEPTH_BUFFER_BIT );
gl.drawArrays( gl.TRIANGLES, 0, 36 );
}
</script>
</body>
</html>
问题出在这一行:
newColor = vec4(oldColor.r * pointColorV,
oldColor.g * pointColorV,
oldColor.b * pointColorV,
1.0);
在 glsl 中,float*vector
操作 returns 向量。由于 pointColorV
是一个向量,您尝试将三个 vec4 对象传递给 vec4 构造函数,这是不可能的。您可以通过在 pointColorV 之后添加正确的调配运算符 .r/.g/.b
来解决该问题。但更好的选择是将整个事情写成一个操作:
newColor = vec4(oldColor.rgb * pointColorV.rgb, 1.0);