webGL基础知识

624 阅读2分钟

坐标体系

线性插值

首先,线性插值不是一个(数)值,而是一种插值方式,这种插值的函数是一次多项式。

那么,什么又叫做插值呢?

在数值分析中,插值(interpolation)是一种通过已知的、离散的数据点,在范围内推求新数据点的过程或方法。求解科学和工程的问题时,这些已知的数据点通常点借由采样、实验等方法获得,通过这些数据我们希望得到一个连续的函数或者是密集的离散方程,从而根据函数或者方程推求一些未知的数据。

根据插值算法不同,插值类型可以分为:

  • 片段插值(临近插值):找到最近的数据值,并分配相同的值。

  • 线性插值:用已知函数 f 在两点的值,近似获得其它点数值。

例如由两点A、B确定了一条直线方程 f=ax+bf = ax + b,我们就可以根据这个函数求得任何 x0 ( A.x < x0 < B.x)对应的值。

  • 其他插值方式如:多项式插值、牛顿插值、样条曲线插值等等。

不同的插值方式精确度不同,方式的选择要再速度、时间、成本等各个维度做权衡。

webGL中的插值函数

  • step(edg,x)

此函数会根据两个数值生成阶梯函数,如果x<edge则返回0.0,否则返回1.0。

  • smoothstep(edg0, edg1, x)

如果x<=edge0则返回0.0;如果x>=edge1则返回1.0,否则
t=clamp((xedge0)/(edge1edge0),0,1) t=clamp((x-edge0)/(edge1-edge0), 0, 1)
返回tt(32t)返回 t*t*(3-2*t)

基本步骤

第一步:创建webGL上下文

    var canvas = document.querySelector("#canvas");
	var gl = canvas.getContext("webgl");
	if (!gl) {
		return;
	}

第二步:创建webGL程序

//2.1创建2个着色器:顶点着色器和片着色器。代码是顶点着色器;片着色器类似
	var source = document.getElementById("vertex-2d").text;
    var vertexShader = gl.createShader(gl.VERTEX_SHADER); // 创建着色器对象
	gl.shaderSource(vertexShader, source); //提供数据源
	gl.compileShader(vertexShader); // 编译 -> 生成着色器
    
//2.2 创建webGL程序,链接2个着色器
  	var program = gl.createProgram();
	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);

第三步:创建缓冲

   var positions = [
		-0.7, -0.5,
		0.7, -0.5,
		-0.7, 0.5,
		0.7, -0.5,
		-0.7, 0.5,
		0.7, 0.5,
	];
   var positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

第四步:清理画布,从缓冲中取数据

//4.1 清理画布
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);//转换坐标
	gl.clearColor(0, 0, 0, 0);// 清理画布
	gl.clear(gl.COLOR_BUFFER_BIT);
    
//4.2 激活webGL程序
	gl.useProgram(program);//启用着色器程序
	gl.enableVertexAttribArray(positionAttributeLocation);//启用对应属性a_position
    
//4.3 从缓冲中取数器
	gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
	// 告诉属性怎么从positionBuffer中读取数据 (ARRAY_BUFFER)
	var size = 2; // 每次迭代运行提取两个单位数据;
	var type = gl.FLOAT; // 每个单位的数据类型是32位浮点型
	var normalize = false; // 不需要归一化数据
	var stride = 0; // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))
	// 每次迭代运行运动多少内存到下一个数据开始点
	var offset = 0; // 从缓冲起始位置开始读取
	gl.vertexAttribPointer(
		positionAttributeLocation, size, type, normalize, stride, offset);

	

第五步:渲染场景

    //运行GL程序
	var primitiveType = gl.TRIANGLES; //图元类型是三角形
	var offset = 0;
	//顶点着色器运行次数,运行6次,每次从缓冲中取得2个值赋值给a_position
	var count = 6;
	gl.drawArrays(primitiveType, offset, count);