在WebGL中将颜色应用于顶点的问题

时间:2018-11-21 15:42:09

标签: glsl webgl webgl2

我用两个三角形作了一个正方形,然后我给顶点分配了颜色,但是无论我给它分配什么颜色,每次给我分配黑色正方形。

这是我的脚本代码:

    <script>

     var canvas = document.getElementById('my_Canvas');
     var gl = canvas.getContext('experimental-webgl');


     var vertices = [
        -0.5,0.5,0.0,
        -0.5,-0.5,0.0,
        0.5,-0.5,0.0,
        0.5,-0.5,0.0,
        0.5,0.5,0.0,
        -0.5,0.5,0.0
     ];

     var colors = [ 0,0,1, 1,0,0, 0,1,0, 1,0,1,];

     var vertex_buffer = gl.createBuffer();

     gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

     gl.bindBuffer(gl.ARRAY_BUFFER, null);


     var vertCode =
        'attribute vec3 coordinates;' +
        'attribute vec3 color;'+
        'varying vec3 vColor;'+

        'void main(void) {' +
           ' gl_Position = vec4(coordinates, 1.0);' +
           'vColor = color;'+
        '}';

     var vertShader = gl.createShader(gl.VERTEX_SHADER);

     gl.shaderSource(vertShader, vertCode);

     gl.compileShader(vertShader);

    var fragCode = 'precision mediump float;'+
        'varying vec3 vColor;'+
        'void main(void) {'+
            'gl_FragColor = vec4(vColor, 1.);'+
        '}';

     var fragShader = gl.createShader(gl.FRAGMENT_SHADER);

     gl.shaderSource(fragShader, fragCode);

     gl.compileShader(fragShader);

     var shaderProgram = gl.createProgram();

     gl.attachShader(shaderProgram, vertShader); 

     gl.attachShader(shaderProgram, fragShader);

     gl.linkProgram(shaderProgram);

     gl.useProgram(shaderProgram);

     gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

     var coord = gl.getAttribLocation(shaderProgram, "coordinates");

     gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

     gl.enableVertexAttribArray(coord);

     gl.clearColor(0.5, 0.5, 0.5, 0.9);

     gl.enable(gl.DEPTH_TEST); 

     gl.clear(gl.COLOR_BUFFER_BIT);

     gl.viewport(0,0,canvas.width,canvas.height);

     gl.drawArrays(gl.TRIANGLES, 0, 6);
  </script>

您可以看到我为每个顶点分配的第四个变量“颜色”。

我也将它传递给了顶点着色器和片段着色器,但是除了黑色以外,它没有给我其他任何颜色。我传递的颜色错误还是图形管道出现问题?

谁能指出代码错误的地方? 请帮忙。

1 个答案:

答案 0 :(得分:1)

您必须为颜色创建缓冲区,就像为顶点坐标创建缓冲区一样。颜色属性的数量必须等于顶点属性的数量。每种颜色都关联一个顶点坐标:

var colors = [ 0,0,1, 1,0,0, 0,1,0, 0,1,0, 1,0,0, 0,0,1 ];

var color_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);  

并且您必须为颜色定义通用顶点属性数据的数组:

gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
var color_index = gl.getAttribLocation(shaderProgram, "color"); 
gl.vertexAttribPointer(color_index, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(color_index);

根据您的代码查看示例:

var canvas = document.getElementById('my_Canvas');
var gl = canvas.getContext('experimental-webgl');

var vertices = [
-0.5,0.5,0.0,   -0.5,-0.5,0.0,  0.5,-0.5,0.0,
  0.5,-0.5,0.0,   0.5,0.5,0.0,  -0.5,0.5,0.0
];

var colors = [ 0,0,1, 1,0,0, 0,1,0, 0,1,0, 1,0,0, 0,0,1, ];

var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

var color_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, null);

var vertCode =
  'attribute vec3 coordinates;' +
  'attribute vec3 color;'+
  'varying vec3 vColor;'+

  'void main(void) {' +
    ' gl_Position = vec4(coordinates, 1.0);' +
    'vColor = color;'+
  '}';

var vertShader = gl.createShader(gl.VERTEX_SHADER);

gl.shaderSource(vertShader, vertCode);

gl.compileShader(vertShader);

var fragCode = 'precision mediump float;'+
  'varying vec3 vColor;'+
  'void main(void) {'+
      'gl_FragColor = vec4(vColor, 1.);'+
  '}';

var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader); 
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);

gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);

gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
var color_index = gl.getAttribLocation(shaderProgram, "color"); 
gl.vertexAttribPointer(color_index, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(color_index);

gl.clearColor(0.5, 0.5, 0.5, 0.9);
gl.enable(gl.DEPTH_TEST); 
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0,0,canvas.width,canvas.height);
gl.drawArrays(gl.TRIANGLES, 0, 6);
<canvas id="my_Canvas" style="border: none;" width="512" height="512"></canvas>