在 WebGL 中绘制四面体

Drawing a tetrahedron in WebGL

我是 WebGL 的新手,我试图在 WebGL.Something 中绘制一个非常简单的四面体,但某处出错了。我正在尝试使用索引并尝试为四面体的每个表面赋予颜色。但是除了背景什么都没有出现在屏幕上。

以下是我试过的程序

function init1(){
  var canvas = document.getElementById("mycanvas");
  var gl = canvas.getContext("experimental-webgl"); 
  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(0.0, 0.0, 0.0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.enable(gl.DEPTH_TEST); 

  var v = document.getElementById("vertex").firstChild.nodeValue;
  var f = document.getElementById("fragment").firstChild.nodeValue;

  var vs = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vs, v);
  gl.compileShader(vs);

  var fs = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fs, f);
  gl.compileShader(fs);

  var program = gl.createProgram();
  gl.attachShader(program, vs);
  gl.attachShader(program, fs);
  gl.linkProgram(program);

  var vertices = [
    0.0000, 0.0000, -1.0000 ,
    0.0000, 0.9428, 0.3333 ,
    -0.8165, -0.4714, 0.3333 ,
    0.8165, -0.4714, 0.3333 
  ]; 

  var indices = [ 
    1, 2, 3, 
    2, 3, 0,
    3, 0, 1,
    0, 1, 2
  ];

  var colors = [
    1.0,  1.0,  1.0,    // white
    1.0,  0.0,  0.0,    //  red
    0.0,  1.0,  0.0,    //  green
    0.0,  0.0,  1.0    // blue
  ];

  var itemDimension = 3;

  var cBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
  program.vColor = gl.getAttribLocation(program, "vColor");
  gl.enableVertexAttribArray(program.vColor);     
  gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0); 



  var vBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
  gl.enableVertexAttribArray(program.aVertexPosition);       
  gl.vertexAttribPointer(program.aVertexPosition, itemDimension, gl.FLOAT, false, 0, 0);

  var ibuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibuffer);                                       
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibuffer);

  var numItems = vertices.length / itemDimension;

  gl.useProgram(program);   

  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  gl.drawElements(gl.TRIANGLES, indices.length, gl.FLOAT, 0 );
}
init1();
<script id="vertex" type="x-shader">

attribute vec3 aVertexPosition;
attribute vec3 vColor;
varying vec4 color;

void main() {
 gl_Position = vec4(aVertexPosition, 0.0, 1.0);
    color = vec4(vColor,1.0); 
}

</script>  
<script id="fragment" type="x-shader">

precision mediump float;
varying vec4 color; 

void main() {
   gl_FragColor = color;
}
</script>        

<canvas id="mycanvas" width="800" height="500"></canvas>

你看过 JavaScript 控制台了吗?

我猜如果你这样做了你会看到错误。

这是 Chrome

中的 JavaScript 控制台

这是 Firefox 中的 WebConsole

第一个错误是因为你的顶点着色器没有编译。你有

attribute vec3 aVertexPosition;

但是

gl_Position = vec4(aVertexPosition, 0.0, 1.0);  // <=- ERROR!!!

您不能将 vec3 放入具有 2 个以上元素(总共 5 个元素)的 vec4 中。正确的代码是

gl_Position = vec4(aVertexPosition, 1.0);

最后一个错误是因为 gl.drawElements 的参数无效

gl.drawElements(gl.TRIANGLES, indices.length, gl.FLOAT, 0 );  // <=- ERROR!!

您不能 gl.FLOAT 类型的索引

你想要

 gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0 );

正在运行

function init1(){
  var canvas = document.getElementById("mycanvas");
  var gl = canvas.getContext("experimental-webgl"); 
  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(0.0, 0.0, 0.0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.enable(gl.DEPTH_TEST); 

  var v = document.getElementById("vertex").text;
  var f = document.getElementById("fragment").text;

  var vs = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vs, v);
  gl.compileShader(vs);

  var fs = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fs, f);
  gl.compileShader(fs);

  var program = gl.createProgram();
  gl.attachShader(program, vs);
  gl.attachShader(program, fs);
  gl.linkProgram(program);

  var vertices = [
    0.0000, 0.0000, -1.0000 ,
    0.0000, 0.9428, 0.3333 ,
    -0.8165, -0.4714, 0.3333 ,
    0.8165, -0.4714, 0.3333 
  ]; 

  var indices = [ 
    1, 2, 3, 
    2, 3, 0,
    3, 0, 1,
    0, 1, 2
  ];

  var colors = [
    1.0,  1.0,  1.0,    // white
    1.0,  0.0,  0.0,    //  red
    0.0,  1.0,  0.0,    //  green
    0.0,  0.0,  1.0    // blue
  ];

  var itemDimension = 3;

  var cBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
  program.vColor = gl.getAttribLocation(program, "vColor");
  gl.enableVertexAttribArray(program.vColor);     
  gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0); 



  var vBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
  gl.enableVertexAttribArray(program.aVertexPosition);       
  gl.vertexAttribPointer(program.aVertexPosition, itemDimension, gl.FLOAT, false, 0, 0);

  var ibuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibuffer);                                       
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibuffer);

  var numItems = vertices.length / itemDimension;

  gl.useProgram(program);   

  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0 );
}
init1();
<script id="vertex" type="x-shader">

attribute vec3 aVertexPosition;
attribute vec3 vColor;
varying vec4 color;

void main() {
 gl_Position = vec4(aVertexPosition, 1.0);
    color = vec4(vColor,1.0); 
}

</script>  
<script id="fragment" type="x-shader">

precision mediump float;
varying vec4 color; 

void main() {
   gl_FragColor = color;
}
</script>        

<canvas id="mycanvas" width="800" height="500"></canvas>