WebGL坐标系

使用浏览器打开示例源码发现,是一个直角三角形,准确地说是看到的图像是三维空间中一个等边三角形平面的投影,等边三角形平面的三个定点分别xyz轴上,说明投影的方向是其中一个坐标轴所在的方向,才能呈现出直角三角形的效果

WebGL中坐标系如下:

![截屏2023-02-24 16.11.02](/Users/a666/Desktop/截屏2023-02-24 16.11.02.png)

以显示器为准,WebGL中顶点坐标的表示方法采用的是相对坐标,相对于canvas而言 WebGL坐标系统。

X轴水平向右,也就是canvas画布的width表示的宽度方向,x等于-1表示canvas画布的左边界,x等于1表示canvas画布的右边界,x等于0对应的是画布宽度方向的中间。

Y轴竖直向上,也就是canvas画布的height表示的高度方向,y等于-1表示canvas画布的下边界,y等于1表示canvas画布的上边界,y等于0对应的是画布高度方向的中间。

Z轴垂直canvas画布朝外,Z值-1和1是Z方向的极限值,GPU成像默认的沿着Z轴投影,你也可以抽象出一个概念,人眼睛位于z轴上,沿着z轴方向去观察物体,如果你在其他的书上看到视图坐标系等其它各类坐标系都是抽象出的概念 都是建立在本节课所说的WebGL 坐标系统之上,例如无人机导航中的所说的机体坐标系、地球坐标系都是直接对现实中事物的描述,三维场景中的各类坐标系与无人机中坐标系没什么区别,但是要显示在屏幕上,就要经过一些处理,这里不再详述,后面的教程后为大家引入各类坐标系概念, 正射投影和透射投影概念。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
<canvas id="webgl" width="500" height="500" style="background-color: #0d72da"></canvas>
<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
  //attribute声明vec4类型变量apos
  attribute vec4 apos;
  void main() {
    //顶点坐标apos赋值给内置变量gl_Position
    //逐顶点处理数据
    gl_Position = apos;
  }

</script>
<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">

  void main() {
    // 逐片元处理数据,所有片元(像素)设置为红色
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
  }

</script>

<script>
  //通过getElementById()方法获取canvas画布
  var canvas=document.getElementById('webgl');
  //通过方法getContext()获取WebGL上下文
  var gl=canvas.getContext('webgl');

  //顶点着色器源码
  var vertexShaderSource = document.getElementById( 'vertexShader' ).innerText;

  //片元着色器源码
  var fragShaderSource = document.getElementById( 'fragmentShader' ).innerText;
  //初始化着色器
  var program = initShader(gl,vertexShaderSource,fragShaderSource);
  //获取顶点着色器的位置变量apos
  var aposLocation = gl.getAttribLocation(program,'apos');

  //9个元素构建三个顶点的xyz坐标值
  var data=new Float32Array([
    0, 0, 0.5,
    0, 0.5, 0,
    2.0, 0, 0
  ]);

  //创建缓冲区对象
  var buffer=gl.createBuffer();
  //绑定缓冲区对象
  gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
  //顶点数组data数据传入缓冲区
  gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
  //缓冲区中的数据按照一定的规律传递给位置变量apos,第二个代码案例vertexAttribPointer方法的第二个参数是2,这里是3
  gl.vertexAttribPointer(aposLocation,3,gl.FLOAT,false,0,0);
  //允许数据传递
  gl.enableVertexAttribArray(aposLocation);
  //开始绘制图形,使用TRIANGLES模式,三点构成一个平面
  gl.drawArrays(gl.TRIANGLES,0,3);

  //声明初始化着色器函数
  function initShader(gl,vertexShaderSource,fragmentShaderSource){
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(vertexShader,vertexShaderSource);
    gl.shaderSource(fragmentShader,fragmentShaderSource);
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);
    var program = gl.createProgram();
    gl.attachShader(program,vertexShader);
    gl.attachShader(program,fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);
    return program;
  }
</script>
</body>
</html>