我试图在每次执行代码时生成随机颜色,并将其传递给片段着色器(绘制三角形)。
通过阅读其他文章,我认为最有效的解决方案似乎是:


在片段着色器中设置一个统一变量
将其链接到javascript变量
使用提供数据的uniform4f写入片段着色器


尝试构建此结构时,我的代码段不显示三角形,而仅显示背景。如果我拿
删除所有处理颜色的线后,三角形再次出现。

 var can = document.getElementById('cont');
var gl = can.getContext('experimental-webgl');
gl.clearColor(0.0, 0.1, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

red = Math.random();
green = Math.random();
blue = Math.random();
alpha = Math.random();
var vertices = [-1,-1,1,-1,0,0.5];
var colorData = [red,green,blue,alpha];

//Create color buffer
var cbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,cbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW);

//Create vertex buffer
var vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);


//Shaders
var vshaderCode = 'attribute vec2 pos;' + 'void main() {gl_Position = vec4 (pos,0.,1.);}';

var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor' + 'void main() {gl_FragColor = uColor;}';


function getShader(shaderSource,type) {
var shad = gl.createShader(type);
gl.shaderSource(shad,shaderSource);
gl.compileShader(shad);
return shad;
}

var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER);
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER);

//Create the program to link shaders

var prog = gl.createProgram();
gl.attachShader(prog,vertexShader);
gl.attachShader(prog,fragmentShader);
gl.linkProgram(prog);

var _position = gl.getAttribLocation(prog, "pos");
var u_ColorLocation = gl.getUniformLocation(prog, "uColor");

//Draw
gl.enableVertexAttribArray(_position);
gl.useProgram(prog);
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0);
gl.uniform4f(u_ColorLocation, colorData);
gl.drawArrays(gl.TRIANGLES, 0, 3);


控制台说gl.uniform4f(u_ColorLocation, colorData);需要五个参数。我不清楚这一点。

即使我将该行更改为gl.uniform4f(u_colorLocation, 0, 0, 1, 1);之类的程序,也不会链接。

然后,如何将我的值从javascript传递到gpu上的片段,以使我的三角形只有一种颜色,由javascript变量驱动?

最佳答案

在碎片处理程序中,您在统一声明后面缺少一个冒号:

var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor;' + 'void main() {gl_FragColor = uColor;}';


如下面的答案中所述,在此处检查编译状态很有用,因为在其自己的文件中编写着色器非常有用。

关于设置制服,有uniformXX(即uniform4f)和uniformXXv(即uniform4fv)变体。 v代表矢量,当您提供数据矢量(例如颜色)时需要使用v。

因此,您也想将其更改为uniform4fv。



 var can = document.getElementById('cont');
var gl = can.getContext('experimental-webgl');
gl.clearColor(0.0, 0.1, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

red = Math.random();
green = Math.random();
blue = Math.random();
alpha = Math.random();
var vertices = [-1,-1,1,-1,0,0.5];
var colorData = [red,green,blue,alpha];

//Create color buffer
var cbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,cbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW);

//Create vertex buffer
var vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);


//Shaders
var vshaderCode = 'attribute vec2 pos;' + 'void main() {gl_Position = vec4 (pos,0.,1.);}';

var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor;' + 'void main() {gl_FragColor = uColor;}';


function getShader(shaderSource,type) {
var shad = gl.createShader(type);
gl.shaderSource(shad,shaderSource);
gl.compileShader(shad);
return shad;
}

var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER);
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER);

//Create the program to link shaders

var prog = gl.createProgram();
gl.attachShader(prog,vertexShader);
gl.attachShader(prog,fragmentShader);
gl.linkProgram(prog);

var _position = gl.getAttribLocation(prog, "pos");
var u_ColorLocation = gl.getUniformLocation(prog, "uColor");

//Draw
gl.enableVertexAttribArray(_position);
gl.useProgram(prog);
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0);
gl.uniform4fv(u_ColorLocation, colorData);
gl.drawArrays(gl.TRIANGLES, 0, 3);

<canvas id="cont"></canvas>

08-07 11:08