WebGL笔记 (侧重理论基础向)

        要把Cesium,three.js 这些玩明白还是要有WebGL的知识的,不然只是官方demo的ctrl-cv侠,本笔记参考的教程 : 2022年WebGL入门教程(完结)_哔哩哔哩_bilibili

 

一、初级(二维)

1.1. 坐标系

        WebGL的工作区在canvas标签中运行,并与canvas有个边距,其内部是一个空间直角坐标系,x,y,z的范围都是∈[ -1 , 1 ] ,z轴是从屏幕里往外延申,最里面是-1

WebGL笔记 (侧重理论基础向)_第1张图片

▲ 图:webGL坐标系

1.2. 生命周期

        顶点缓冲区:功能大概像画画一样,先把图形边框绘制出来,绘制出点位

        uniform数据:把顶点缓冲区的数据传给顶点着色器

        顶点着色器:给顶点画颜色

        图元装配:把顶点数据转换为矢量数据,如:存在3个顶点,这3个点是要绘制成一个面,还是三条线,还是一个点一条直线,还是三个点,等等。

        光栅器:矢量转栅格

        片元着色器:给栅格数据附上纹理和颜色

        归属测试:暂定

        模板测试:暂定

        深度测试:暂定

        融合:融合各方面的数据

        抖动:动态效果

        颜色缓冲区:用户可以看到的区域

WebGL笔记 (侧重理论基础向)_第2张图片

1.3. 基础绘制

  1.3.1 绘制点 (输入固定位置)

        流程:初始化webgl控件、初始化着色器、初始化缓冲区、开始绘制



  
    
    
    
    Document
    
    // 第三方库,集成了一些坐标投影函数
    
  

  
    
  

1.3.2 绘制点(鼠标动态点击绘制)

          相较于固定输入的一个点位,新增的难点:获取点击时候的显示器坐标、显示器坐标转换为WebGL坐标(像素坐标转归一化zuo)

/** 其他省略,和上一个代码区域里面一样

..... 

*/

// 使用顶点缓冲区
function initBuffer() {
  let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");

  document.addEventListener("mousedown", function (e) {
    debugger;
    let x = e.clientX;
    let y = e.clientY;
    let rect = e.target.getBoundingClientRect();
    let pointx = (x - rect.left - 512) / 512; // 屏幕转WebGL坐标
    let pointy = (350 - (y - rect.top)) / 350;
    points.push(pointx);
    points.push(pointy);
    points.push(0);

    let pointPosition = new Float32Array(points);
    let pointBuffer = webgl.createBuffer(); // 创建缓冲区
    webgl.bindBuffer(webgl.ARRAY_BUFFER, pointBuffer); // 绑定缓冲区
    webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW); // 缓冲区输入数据
    webgl.enableVertexAttribArray(aPsotion); // 启动:开始向GPU传输数据
    webgl.vertexAttribPointer(aPsotion, 3, webgl.FLOAT, false, 0, 0); // 配置项:位置、一次从顶点数组取几个数、顶点数组数据类型、是否归一化、间隔字节、偏移字节

    webgl.clearColor(0.0, 0.0, 0.0, 1.0);
    webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
    webgl.drawArrays(webgl.POINTS, 0, points.length / 3); // 绘制点
  });

  let uniformProj = webgl.getUniformLocation(webgl.program, "proj");
  webgl.uniformMatrix4fv(uniformProj, false, projMat4);
}
function draw() {
  webgl.clearColor(0.0, 0.0, 0.0, 1.0);
  webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
}

 1.3.3 绘制线

var points = [];
var colors=[];
function initBuffer() {
    let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");
    let arr = [100.0,100.0,0,    200.0,200.0,0, 300.0,200.0,0 ,400,600,0];
    let vertexArr = new Float32Array(arr);
    let trangleBuffer =  webgl.createBuffer();
    webgl.bindBuffer(webgl.ARRAY_BUFFER,trangleBuffer);
    webgl.bufferData(webgl.ARRAY_BUFFER,vertexArr,webgl.STATIC_DRAW);
    webgl.enableVertexAttribArray(aPsotion);
    webgl.vertexAttribPointer(aPsotion,3, webgl.FLOAT, false, 0, 0);

    let uniformProj = webgl.getUniformLocation(webgl.program, "proj");
    webgl.uniformMatrix4fv(uniformProj, false, projMat4);
}
function draw() {
    webgl.clearColor(0.0, 0.0, 0.0, 1.0);
    webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
    webgl.drawArrays(webgl.LINES,0,4);        // 绘制线
    //webgl.drawArrays(webgl.LINE_STRIP,0,4)  // 绘制折现
    //webgl.drawArrays(webgl.LINE_LOOP,0,4)   // 绘制闭合线 
    
}

1.3.4 绘制三角形

var points = [];
var colors=[];
function initBuffer() {
    let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");
    let arr = [100.0,100.0,0,    200.0,200.0,0, 300.0,200.0,0 ,400,600,0];
    let vertexArr = new Float32Array(arr);
    let trangleBuffer =  webgl.createBuffer();
    webgl.bindBuffer(webgl.ARRAY_BUFFER,trangleBuffer);
    webgl.bufferData(webgl.ARRAY_BUFFER,vertexArr,webgl.STATIC_DRAW);
    webgl.enableVertexAttribArray(aPsotion);
    webgl.vertexAttribPointer(aPsotion,3, webgl.FLOAT, false, 0, 0);

    let uniformProj = webgl.getUniformLocation(webgl.program, "proj");
    webgl.uniformMatrix4fv(uniformProj, false, projMat4);
}
function draw() {
    webgl.clearColor(0.0, 0.0, 0.0, 1.0);
    webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
    webgl.drawArrays(webgl.TRIANGLES,0,3);
    // webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);
    // webgl.drawArrays(webgl.TRIANGLE_FAN,0,4); 
}

WebGL笔记 (侧重理论基础向)_第3张图片

图 三角形的绘制类型

1.3.5 索引缓冲区

         使用索引实现点位复用,以达到不用传入多个相同的点

WebGL笔记 (侧重理论基础向)_第4张图片

1.4. 纹理

1.4.1 纹理映射

        理论: 在片元着色器中运行。原理:图片四个点作为控制点,然后插值映射到接受区域。

1.4.2 多重纹理

        (1)理论:一次性绘制多个纹理

        (2) 图像坐标系与纹理坐标系

WebGL笔记 (侧重理论基础向)_第5张图片

▲ 图:图像坐标转纹理坐标    

1.4.3 动态变换与动画理论

        (1)基本理论

                Matrix4进行矩阵运算,一秒内快速变换数十次位置,形成动画。

        (2)数学运算

WebGL笔记 (侧重理论基础向)_第6张图片

 ▲图:平移、缩放、旋转的矩阵运算

二、 中级(三维)

2.1 视点、目标点、视线

        意义:camera视角控制

WebGL笔记 (侧重理论基础向)_第7张图片

 图:视点、目标点、视线

2.2 可视域

  意义:提升渲染效率

(1)正视投影

WebGL笔记 (侧重理论基础向)_第8张图片

 图:正视投影

(2)透视投影

WebGL笔记 (侧重理论基础向)_第9张图片

  图:透视投影

2.3 深度缓冲区与多边形偏移

          深度缓冲区:三维空间中,保存对象z值的缓冲区

          深度冲突:z值相同或十分相近的两个物体对象,会产生重影,解决方案就是深度检测算法

          多边形偏移:进行z值的offset偏移设置,使得z值稍微有差距,解决重影问题。

2.4 绘制正方体

知识点:三维场景中,逆时针绘画为正面,顺时针为背面

2.5 光照

1. 基本概念

        光源:平行光,点光源,环境光(各个方向光照一样)

        反射光:镜面反射,漫反射,环境反射

        法线:垂直于表面的向量


  未完待续

你可能感兴趣的:(WebGL,html5,javascript,图形渲染)